Reverse-Engineeren von Hafas-Verbindungsanfragen

2,324 views
Skip to first unread message

Andreas (Öffi)

unread,
Jul 12, 2012, 6:17:09 PM7/12/12
to public-transport...@googlegroups.com
Guckt mal auf folgende URL:

http://reiseauskunft.insa.de/bin/query.exe/dn?start=Suchen&REQ0JourneyStopsS0ID=A%3D1%40L%3D13002&REQ0JourneyStopsZ0ID=A%3D1%40L%3D8010205&REQ0HafasSearchForw=1&REQ0JourneyDate=12.07.12&REQ0JourneyTime=23:56&REQ0JourneyProduct_prod_section_0_5=1&REQ0JourneyProduct_prod_section_0_6=1&REQ0JourneyProduct_prod_section_0_0=1&REQ0JourneyProduct_prod_section_0_1=1&REQ0JourneyProduct_prod_section_0_2=1&REQ0JourneyProduct_prod_section_0_3=1&REQ0JourneyProduct_prod_section_0_4=1

Das ist eine Verbindungsanfrage am Hafas-System. Leider sind diese Webseiten nur schwerlich parsebar, und meistens bricht der Code bei Layout-Wechseln, oder bei anderen Verkehrsverbünden die eigentlich dieselbe Software einsetzen.

Die mobilen Apps hängen noch einen Parameter an die URL, nämlich "h2g-direct=11":

http://reiseauskunft.insa.de/bin/query.exe/dn?start=Suchen&REQ0JourneyStopsS0ID=A%3D1%40L%3D13002&REQ0JourneyStopsZ0ID=A%3D1%40L%3D8010205&REQ0HafasSearchForw=1&REQ0JourneyDate=12.07.12&REQ0JourneyTime=23:56&REQ0JourneyProduct_prod_section_0_5=1&REQ0JourneyProduct_prod_section_0_6=1&REQ0JourneyProduct_prod_section_0_0=1&REQ0JourneyProduct_prod_section_0_1=1&REQ0JourneyProduct_prod_section_0_2=1&REQ0JourneyProduct_prod_section_0_3=1&REQ0JourneyProduct_prod_section_0_4=1&h2g-direct=11

Zurück kommt eine Binärdatei. Ich habe bereits herausgefunden, daß man die abspeichern und per gzip entpacken kann.

Wenn man sich das Ergebnis mit einem Hex-Editor ansieht, sieht man einen grossen Block mit den Strings (0-terminiert) ab 0xfe und davor und danach diverse Daten.

Auch rausgefunden: Leipzig Hbf hat die Nr. 8010205. Das ist in Hex 0x007a39dd. Das findet sich an Stelle 0x4250 wieder, allerdings als little endian, also dd 39 7a 00.

Ich erwarte, dass es evtl. einen Block gibt, in dem u.a. die Verbindungsanfrage wiederholt wird. Und dann insgesamt 3 Fahrten. Die Strings C0-0, C0-1, C0-2 sind uebrigens die IDs der drei Fahrten, daran kann man evtl. die Strukturgrenzen erkennen.

Damit wir alle von den gleichen Daten reden, hänge ich die entpackten Daten mal an. Zusammen mit einen Screenshot, damit die restlichen Daten klar sind (Uhrzeiten, Namen der Verkehrsmittel). UPDATE: Google erlaubt kein Anhängen von Binärdateien - ich schicke sie jedem privat zu (bitte melden).

Ziel dieses Unterfangens ist im Prinzip eine Spezifikation wie das Format aufgebaut ist. Die Programmierung anhand dieser Spec kann ich dann wieder machen, falls sich nicht jemand drum reisst (-:

Stefan Lindecke

unread,
Jul 13, 2012, 4:36:53 AM7/13/12
to public-transport...@googlegroups.com
Du bist Dir auch sicher, das du die Daten in der gewuenschten Form ueberhaupt weiterverarbeiten darfst ? 
  
Schau Dir auf alle Faelle erstmal die AGBs an. Im Normalfall wird dieser Vorgang naemlich ausdruecklich untersagt. Dafuer gibt es normierte Schnittstellen des Anbieters : http://www.hacon.de/hafas/internet/schnittstellen

Andreas (Öffi)

unread,
Jul 13, 2012, 6:44:08 AM7/13/12
to public-transport...@googlegroups.com
On Friday, July 13, 2012 10:36:53 AM UTC+2, Stefan Lindecke wrote:
Du bist Dir auch sicher, das du die Daten in der gewuenschten Form ueberhaupt weiterverarbeiten darfst ?

Keine Ahnung - ich bin kein Anwalt. Hier geht es aber erstmal nur ums Analysieren.

null

unread,
Jul 13, 2012, 7:08:00 AM7/13/12
to public-transport...@googlegroups.com

Andreas (Öffi)

unread,
Jul 13, 2012, 7:15:44 AM7/13/12
to public-transport...@googlegroups.com
On Friday, July 13, 2012 1:08:00 PM UTC+2, null wrote:
 
Welche mobile App? Android reversing ist meistens einfacher als das Protokoll.

Es ist diese hier:

https://play.google.com/store/apps/details?id=de.hafas.android.nasa

Leider ist sie obfuscated.

Das Einlesen der Daten findet vermutlich in der Klasse de/hafas/a/di statt, aber wo geparsed wird, hab ich bis jetzt noch nicht herausgefunden.

Malte Starostik

unread,
Jul 13, 2012, 4:38:07 PM7/13/12
to public-transport...@googlegroups.com
Der letzte String ist sowas wie eine Anfrage-Id, die auch auf der Browser-Seite in weiterführenden Links verwendet wird. z.B. ident=2w.03129616.1342210019, im BLOB ohne das ident=. Der letzte Teil davon nach dem . ist der Zeitpunkt der Anfrage als UNIX Timestamp. Die Reihenfolge der Strings erschließt sich mir noch nicht ganz, evtl. ist die auch willkürlich und alles weitere ergibt sich aus den Referenzen in diese Tabelle. Möglicherweise alles in allem eine direkte Serialisierung einer Hafas-spezischen Klasse? Ich werd mir den nicht-druckbaren Kram nachher nochmal vornehmen, vielleicht zeigt sich dann ja noch das eine oder andere Detail.
Aber wie Stefan schon sagt, kann man nicht evtl. auf eine offizielle API aufsetzen? Die Seite ist ja nicht gerade aussagekräftig...wollen vermutlich was dafür? Ebenfalls IANAL, aber kann mir kaum vorstellen, dass das Abrufen des BLOBS *vom Endgerät aus* problematisch ist.

Andreas Schildbach

unread,
Jul 13, 2012, 5:15:06 PM7/13/12
to public-transport...@googlegroups.com
On 07/13/2012 10:38 PM, Malte Starostik wrote:

> Der letzte String ist sowas wie eine Anfrage-Id, die auch auf der
> Browser-Seite in weiterführenden Links verwendet wird. z.B.
> ident=2w.03129616.1342210019, im BLOB ohne das ident=. Der letzte Teil
> davon nach dem . ist der Zeitpunkt der Anfrage als UNIX Timestamp.

Ja, das identifiziert eine Verbindungs-Alternative.

> Die
> Reihenfolge der Strings erschließt sich mir noch nicht ganz, evtl. ist
> die auch willkürlich und alles weitere ergibt sich aus den Referenzen in
> diese Tabelle. Möglicherweise alles in allem eine direkte Serialisierung
> einer Hafas-spezischen Klasse?

Serialisierung gut moeglich, aber sicherlich nicht Java. Ich kann zu den
Strings noch einiges sagen, recht sicher ist zum Beispiel dass die
Strings bereits um doppelte bereinigt wurden. So kommt Leipzig Hbf z.B.
nur einmal vor, obwohl es 3 Verbindungen von dort gibt.

> Aber wie Stefan schon sagt, kann man nicht evtl. auf eine offizielle API
> aufsetzen?

Es gibt keine offizielle API, und die XML-API wurde abgeschaltet.

Cheers,

Andreas

Harald Schilly

unread,
Jul 13, 2012, 5:21:26 PM7/13/12
to public-transport...@googlegroups.com
2012/7/13 Andreas Schildbach <and...@schildbach.de>:
> Serialisierung gut moeglich, aber sicherlich nicht Java.

ich kenn mich mit blobs nicht aus, aber es gibt in java mehrere
(übergreifende) möglichkeiten zum serialisieren. vielleicht passt ja
der BOM oder sonst eine markierung zu einer existierenden
serialisierung?
aus dem kopf kenn ich zb die seite, die thrift, protobuf und ähnliche erwähnt.
http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

h

Malte Starostik

unread,
Jul 13, 2012, 11:13:21 PM7/13/12
to public-transport...@googlegroups.com
Zwischenergebnis:

(soweit nicht anders angegeben, sind alle Zahlwerte vorzeichenlos, 16 Bit breit und Little-Endian kodiert)

Bei Offset 0x24 befindet sich der Offset zur String-Tabelle
Bei Offset 0x36 befindet sich der Offset zur Stations-Tabelle
Bei Offset 0x4a befindet sich eine noch unbekannte Struktur, deren Länge an Offset 0x4c steht.
Im Anschluss daran, also bei 0x4a + *0x4c, befindet sich die Verbindungs-Tabelle.

Verbindungs-Tabelle:
Es handelt sich um eine Sequenz von 40 Byte großen Einträgen.
Aufbau der Einträge (bekannte Felder sind sicher Integer, unbekannte mutmaßlich auch):
Abfahrtszeit - 100 * Stunden + Minuten
Abfahrtsort - Index in die Stations-Tabelle
Ankunftszeit - s. Abfahrtszeit
Ankunftsort - s. Abfahrtsort
unbekannt
Verkehrslinie - Index in die String-Tabelle
unbekannt
unbekannt
unbekannt
unbekannt

Die Tabelle enthält einen Eintrag pro TEILverbindung. Der Beginn einer neuen Gesamtverbindung gemäß Suchanfrage lässt sich daran erkennen, dass der Abfahrtsort null ist - andere mögliche Identifizierungen sind noch nicht bekannt.

Die String-Tabelle ist eine Aneinanderreihung von NUL-terminierten Strings. Referenzen in diese Tabelle sind als Byte-Offset relativ zum start der String-Tabelle gegeben, nicht als Index des referenzierten Strings.
Die Stations-Tabelle habe ich noch nicht weiter betrachtet, außer dass es sich um eine Sequenz aus 14 Byte großen Einträgen handelt, am Beginn jedes Eintrags steht der String-Offset des Stations-Namens.

Hier ein PoC zum dekodieren der gegunzipten Daten:

#!/usr/bin/perl

use strict;

my $raw;

read STDIN, $raw, 0x10000;

my (
$string_offset,
$location_offset,
$header_size
) = unpack '(@36v @54v @76v)', $raw;

sub lookup_string {
return unpack '(@' . ($string_offset + $_[0]) . 'Z*)', $raw;
}

sub lookup_loc {
return lookup_string unpack '(@' . ($location_offset + 0xe * $_[0]) . 'v)', $raw;
}

my @conn = unpack '(a20)*', substr $raw, 0x4a + $header_size, $string_offset - 0x4a - $header_size;

foreach (@conn) {
my (
$time1, $loc1,
$time2, $loc2,
$unknown1,
$line,
$unknown2, $unknown3, $unknown4, $unknown5
) = unpack 'v*', $_;
print "---\n" if $loc1 == 0;
printf "Linie %s\n ab: %.2d:%.2d %s\n an: %.2d:%.2d %s\n [%.4x, %.4x, %.4x, %.4x, %.4x]\n",
lookup_string($line),
$time1 / 100, $time1 % 100, lookup_loc($loc1),
$time2 / 100, $time2 % 100, lookup_loc($loc2),
$unknown1, $unknown2, $unknown3, $unknown4, $unknown5;
}


Beispiel: am 13.7.12 um 10:30 von Leipzig, Hildebrandstr. nach Leipzig, Paunsdorf Nord (vier Verbindungen mit unterschiedlicher Anzahl Umsteiger):

HTML-Version: http://reiseauskunft.insa.de/bin/query.exe/dn?start=Suchen&REQ0JourneyStopsS0ID=A%3D1%40L%3D13006&REQ0JourneyStopsZ0ID=A%3D1%40L%3D11536&REQ0JourneyDate=13.07.12&REQ0JourneyTime=10:30

curl -s 'http://reiseauskunft.insa.de/bin/query.exe/dn?start=Suchen&REQ0JourneyStopsS0ID=A%3D1%40L%3D13006&REQ0JourneyStopsZ0ID=A%3D1%40L%3D11536&REQ0JourneyDate=13.07.12&REQ0JourneyTime=10:30&h2g-direct=11' | gunzip | ./decode
---
Linie Str 11
ab: 10:29 Leipzig, Hildebrandstr.
an: 10:32 Leipzig, Raschwitzer Straße
[0002, 0000, 0000, 0003, 0000]
Linie Bus 79
ab: 10:33 Leipzig, Raschwitzer Straße
an: 10:58 Leipzig, Theodor-Heuss-Straße
[0002, 0000, 0000, 000b, 0000]
Linie Str 7
ab: 11:00 Leipzig, Theodor-Heuss-Straße
an: 11:08 Leipzig, Paunsdorf Nord
[0002, 0000, 0000, 0013, 0000]
---
Linie Str 11
ab: 10:29 Leipzig, Hildebrandstr.
an: 10:42 Leipzig, Wilhelm-Leuschner-Platz
[0002, 0000, 0000, 00ce, 0000]
Linie Str 8
ab: 10:45 Leipzig, Wilhelm-Leuschner-Platz
an: 11:12 Leipzig, Paunsdorf Nord
[0002, 0000, 0000, 00d6, 0000]
---
Linie Str 11
ab: 10:39 Leipzig, Hildebrandstr.
an: 10:53 Leipzig, Augustusplatz
[0002, 0000, 0000, 0191, 0000]
Linie Str 7
ab: 10:56 Leipzig, Augustusplatz
an: 11:18 Leipzig, Paunsdorf Nord
[0002, 0000, 0000, 0199, 0000]
---
Linie Str 11
ab: 10:49 Leipzig, Hildebrandstr.
an: 10:52 Leipzig, Raschwitzer Straße
[0002, 0000, 0000, 0254, 0000]
Linie Bus 79
ab: 10:53 Leipzig, Raschwitzer Straße
an: 11:18 Leipzig, Theodor-Heuss-Straße
[0002, 0000, 0000, 025c, 0000]
Linie Str 7
ab: 11:20 Leipzig, Theodor-Heuss-Straße
an: 11:28 Leipzig, Paunsdorf Nord
[0002, 0000, 0000, 0264, 0000]
---
Linie Str 11
ab: 10:49 Leipzig, Hildebrandstr.
an: 11:02 Leipzig, Wilhelm-Leuschner-Platz
[0002, 0000, 0000, 031f, 0000]
Linie Str 8
ab: 11:05 Leipzig, Wilhelm-Leuschner-Platz
an: 11:32 Leipzig, Paunsdorf Nord
[0002, 0000, 0000, 0327, 0000]

Malte Starostik

unread,
Jul 13, 2012, 11:16:24 PM7/13/12
to public-transport...@googlegroups.com

hmm...genauerer gesagt sind die zu Beginn erwähnen Offsets wahrscheinlich 32 Bit breit, aber die String-Tabelle kann max 64k groß werden, da die Offsets da rein definitiv 16 Bit breit sind

Malte Starostik

unread,
Jul 14, 2012, 11:13:54 AM7/14/12
to public-transport...@googlegroups.com
So, bevor das hier zum Selbstgespräch wird, aber um trotzdem Fortschritte zu dokumentieren, hab ich mal die bisher bekannten Infos hier gesammelt und werde vorerst nur dort aktualisieren:

https://docs.google.com/spreadsheet/ccc?key=0Aun-eLXVl8Y0dFplcHNpdGZieUVDN24tRDYyb0JRRWc

Andreas Schildbach

unread,
Jul 14, 2012, 11:52:16 AM7/14/12
to public-transport...@googlegroups.com
Sehr cool, das klingt alles super! Ich bin im Moment auf einem
Bitcoin-Hackathon, aber werde Deine Erkenntnisse am Montag versuchen in
Java-Code zu giessen.

Malte Starostik

unread,
Jul 16, 2012, 3:53:26 AM7/16/12
to public-transport...@googlegroups.com
Dann erstmal viel Vergnügen damit. Es fehlen noch einige Puzzleteile, inkl. ganzer Blöcke im hinteren Teil der Daten, aber ich denke die wesentlichen Infos sind geknackt. Hoffe, die Liste ist soweit verständlich.

Andreas Schildbach

unread,
Jul 16, 2012, 5:20:05 PM7/16/12
to public-transport...@googlegroups.com
Wie soll ich Ergaenzungen anbringen?

Z.B. glaube ich, dass Zeilen 71 (Typ) und 72 (Ankunfts-Zeit) vertauscht
gehoeren.

Andreas Schildbach

unread,
Jul 16, 2012, 7:46:25 PM7/16/12
to public-transport...@googlegroups.com
Es gibt leider noch Aufklaerungsbedarf... Ich bin noch auf der Suche von
den Verbindungs-IDs C0-1, C0-2, C0-0 u.s.w. In dem von mir hochgeladenen
Beispiel finden sich die Referenzen auf die Strings im letzten grossen
Teil des Blobs.

Ganz aehnlich verhaelt es sich bei den Richtungsangaben (z.B. "Leipzig,
Gohlis-Nord"), diese Referenz findet sich ebenfalls weit hinten.

Irgendwo muessen auch die Linien noch in Klassen aufgeschluesselt
werden, die "Str 12" has naemlich folgende Parameter die ich gerne
auslesen wuerde:

Operator=Leipziger Verkehrsbetriebe
AdminCode=LVTRAM
Class=32 (die Zahl ist quasi ein Bitfeld, wobei immer nur ein Bit
gesetzt sein kann)
HafasName=Str 12
Category="Strb "
InternalCat=STR

Nicht ganz so wichtig, aber irgendwo stecken auch Fahrpreis-Angaben bzw.
Namen von Tickets (Stichworte Einzelfahrkarte, Kurzstrecke, EUR, Tariff).

Es ist auch moeglich, dass irgendwo eine "Polyline" steckt, d.h. die
genaue Streckenfuehrung angegeben ist.

Malte Starostik

unread,
Jul 17, 2012, 2:40:24 AM7/17/12
to public-transport...@googlegroups.com
Die Reihenfolge von Typ und Ankunft habe ich korrigiert. Wenn ich jetzt noch rauskriege, wie ich Dir bei dem Dokument Schreibrechte einräumen kann...



Es gibt leider noch Aufklaerungsbedarf... Ich bin noch auf der Suche von
den Verbindungs-IDs C0-1, C0-2, C0-0 u.s.w. In dem von mir hochgeladenen
Beispiel finden sich die Referenzen auf die Strings im letzten grossen
Teil des Blobs.
Ja, der Teil fehlt noch komplett. Zum Verständnis: wozu werden diese Verbindungs-IDs verwendet? :(
 

Ganz aehnlich verhaelt es sich bei den Richtungsangaben (z.B. "Leipzig,
Gohlis-Nord"), diese Referenz findet sich ebenfalls weit hinten.

Irgendwo muessen auch die Linien noch in Klassen aufgeschluesselt
werden, die "Str   12" has naemlich folgende Parameter die ich gerne
auslesen wuerde:

Operator=Leipziger Verkehrsbetriebe
AdminCode=LVTRAM
Class=32 (die Zahl ist quasi ein Bitfeld, wobei immer nur ein Bit
gesetzt sein kann)
HafasName=Str   12
Category="Strb    "
InternalCat=STR

Die Strings hab ich gesehen und eine Referenz weiter hinten erwartet, aber noch nicht danach gesucht.


Nicht ganz so wichtig, aber irgendwo stecken auch Fahrpreis-Angaben bzw.
Namen von Tickets (Stichworte Einzelfahrkarte, Kurzstrecke, EUR, Tariff).

Es ist auch moeglich, dass irgendwo eine "Polyline" steckt, d.h. die
genaue Streckenfuehrung angegeben ist.
Möglich, wenn sich das nicht aus den Koordinaten der Haltestellen ergibt. Oder ist mit einer schematisierten Version zu rechnen?
Komme aber frühestens heute Abend wieder dazu.

Andreas Schildbach

unread,
Jul 17, 2012, 5:12:14 AM7/17/12
to public-transport...@googlegroups.com
On 07/17/2012 08:40 AM, Malte Starostik wrote:

> Ja, der Teil fehlt noch komplett. Zum Verständnis: wozu werden diese
> Verbindungs-IDs verwendet? :(

Ich verwendet sie bisher, um doppelte zu erkennen. Wenn Du auf "later"
oder "previous connections" drueckst, kommen ggf. Verbindungen, die Du
schon hattest. Die willst Du natuerlich nicht doppelt anzeigen.

Im Moment ist es vielleicht einfach ein guter Weg, um die Struktur zu
erkennen. In meinem Beispiel-Datenblock sind die String-Referenzen an
folgenden Stellen kodiert:

C0-1: $46ea
C0-2: $4998
C0-0: $4c1c

Die Abstaende betragen $2ae bzw. $284. Es sieht fuer mich so aus, als ob
alle Verbindungen im hinteren Datenblock nochmal wiederholt werden, ggf.
ausfuehrlicher.

> Möglich, wenn sich das nicht aus den Koordinaten der Haltestellen
> ergibt. Oder ist mit einer schematisierten Version zu rechnen?

Zu rechnen ist mit einem detaillierten Linienverlauf, der auch zwischen
den Haltestellen auf dem Gleiskoerper bzw. der Strasse verlaeuft.
Allerdings vermutlich doch nicht bei der INSA, denn auf deren Webseite
werden derzeit auch einfach nur die Haltestellen per Luftlinie
verbunden. Grundsaetzlich kann Hafas aber entsprechende Polylines liefern.

Cheers,

Andreas

Andreas Schildbach

unread,
Jul 17, 2012, 5:43:41 AM7/17/12
to public-transport...@googlegroups.com
On 07/17/2012 08:40 AM, Malte Starostik wrote:

> Die Reihenfolge von Typ und Ankunft habe ich korrigiert.

Ich habs nochmal korregiert. Ich weiss, es sieht komisch aus, aber das
Feld "Typ" (dessen Sinn noch unklar ist) scheint wirklich zwischen
Ankunfts-Zeit und Ankunfts-Haltestelle zu stehen.

Malte Starostik

unread,
Jul 17, 2012, 7:43:08 AM7/17/12
to public-transport...@googlegroups.com
Kann ich nicht bestätigen. Ich habe z.B.:
A7 03 = Ab um 9:35
00 00 = Ab bei Hst #0
AE 03 = An um 9:42
01 00 = An bei Hst #1
02 00 = kein Fußweg
...

gefolgt von:
AE 03 = Ab um 9:42
01 00 = Ab bei Hst #1
B1 03 = An um 9:45
02 00 = An bei Hst #2
01 00 = Fußweg
...

und dann
BA 03 = Ab um 9:54
02 00 = Ab bei Hst #2
EC 03 = An um 10:04
03 00 = An bei Hst #3
02 00 = kein Fußweg

Bin mir da extrem sicher, weil ich etliche Abfragen dekodiert und im Klartext ausgegeben habe. Hierfür zuständig ist die Zeile:

@section{qw(time1 station1 time2 station2 type line platform1 platform2 unk1 notes)} = unpack 'vvvvvvvvvv';

und hinterher wird $section{type} als "Fußweg" oder "Fahrverbindung" ausgeben. Das stimmte immer.

Andreas Schildbach

unread,
Jul 17, 2012, 5:37:05 PM7/17/12
to public-transport...@googlegroups.com
On 07/17/2012 01:43 PM, Malte Starostik wrote:

> Kann ich nicht bestätigen. Ich habe z.B.:

Stimmt, Du hast recht. Ich bin von den Daten getrickt worden (-:

Ich habe meine Änderung im Dokument rückgängig gemacht.

Solltest Du übrigens einen Blick auf den aktuellen Java-Code werfen wollen:

git clone https://code.google.com/p/public-transport-enabler/
cd public-transport-enabler
git checkout hafas-binary
less enabler/src/de/schildbach/pte/NasaProvider.java

Robert

unread,
Jul 23, 2012, 2:26:51 AM7/23/12
to public-transport...@googlegroups.com
Ich habe mir die offizielle App mal genauer angesehen. Verschleierung macht es zwar deutlich schwieriger, das Datenmodell zu entschlüsseln, aber auch nicht unmöglich. Ich habe bei der Analyse die Sachen, die ich gerade herausgefunden hatte, in ein Standalone-Javaprogramm gegossen. Ich muss heute Abend mal sehen, wie ich das am besten teilen kann.

Bisher habe ich ca. 80% des Excels im Code nachvollziehen können. Inhaltlich stimmt es weitestgehend, wobei es noch einige zusätzliche Prüfungen im Code gibt und einige Offsets und Größen nicht hart codiert sind, sondern ebenfalls in der Datei stecken.

Zudem habe ich noch einige Fragezeichen auflösen können. Achso, und die Attribute für Verbindungen (die gesuchte ID) und für Teilstrecken (z. B. HafasName) sind in einer Schlüssel-Wert-Tabelle abgelegt. Details folgen im Code. ;-)

Andreas Schildbach

unread,
Jul 23, 2012, 5:21:10 AM7/23/12
to public-transport...@googlegroups.com
Hallo Robert,

das klingt ja super! Ich hatte sowas mit Attribut-Wertepaaren schon
vermutet, nachdem es in der XML-Schnittstelle auch einen groesseren
Bereich dafuer gibt.

Du kannst mir Deine Klassen einfach per Mail schicken, oder in ein Git-
oder SVN-Repository einchecken auf das ich Zugriff habe. Ich werde
probieren, Deine zusaetzlichen Erkenntnisse im "Excel"-Sheet zu
dokumentieren, oder wenn Dir das lieber ist kannst Du das auch machen.

Ich habe den aktuellen Stand im public-transport-enabler als branch
"hafas-binary" auf Google Code gepushed.

http://code.google.com/p/public-transport-enabler/source/browse/?name=hafas-binary

Wenn alles fertig ist, werde ich diesen Branch auf master mergen.

Cheers,

Andreas

Robert

unread,
Jul 23, 2012, 9:19:28 AM7/23/12
to public-transport...@googlegroups.com
Ich habe einen GitHub-Account, da könnte ich das einfach einstellen. Oder ich forke einfach dein Repo, dann kann ich ggf. deine Umsetzung erweitern bzw. etwas an den "Originalcode" anpassen. Vorausgesetzt, ich bekomme Maven entsprechend eingerichtet und was man sonst noch dafür braucht (irgendein Webserver, Tomcat?). Wobei es ja eigentlich ganz normale Javaklassen sind, also sollte sich das auch in Eclipse importieren lassen...

Das Excel habe ich lokal schon etwas erweitert und mir die Änderungen markiert. Das kann ich mit hochladen oder auch selbst eintragen, wenn ich Schreibzugriff bekomme. Ich habe bei mir auch die Zeilen markiert, für dich ich schon Abfragecode gesehen und nachvollzogen habe, und das ist wie gesagt schon ein Großteil.

Andreas Schildbach

unread,
Jul 23, 2012, 9:51:10 AM7/23/12
to public-transport...@googlegroups.com
# clone repo
git checkout https://code.google.com/p/public-transport-enabler/

cd public-transport-enabler

# change branch
git checkout hafas-binary

# build
mvn clean package

Ich teste die Aenderungen immer mit den "Unit-Tests". Du kannst aber
auch einfach eine Klasse mit main-Methode versehen oder sowas.

Du kannst dann alles auf Dein GitHub-Repo pushen und ich hol mir die
Aenderungen von dort.

Nutzt Du Ubuntu? Dann kannst Du alles noetige mit "apt-get install
maven" installieren.

Bzgl. des Excel-Schreibzugriffs, frag mal Malte Starostik - er hat die
Adminrechte an dem Excel.

Robert

unread,
Jul 23, 2012, 10:53:22 AM7/23/12
to public-transport...@googlegroups.com
Ich habe zwar eine Ubuntu-VM, aber ich entwickle normalerweise unter Windows mit Eclipse. Das bringt aber glaube ich auch schon JUnit mit, also geht es vermutlich schneller und gewohnter wenn ich die Klassen mit Eclipse lade.

"Richtige" Unittests wären hier natürlich ideal, um die Ergebnisse zweier Abfragemethoden zu vergleichen, aber praktisch gesehen wird es wohl immer minimale, erlaubte Abweichungen geben. Ich gebe in meiner Testklasse momentan auch nur alles mögliche zu den Verbindungen aus und überprüfe dann von Hand, ob das zu den Webergebnissen passt.

Andreas Schildbach

unread,
Jul 24, 2012, 5:18:03 AM7/24/12
to public-transport...@googlegroups.com
Woran haengts denn im Moment? Du kannst mir wie gesagt Deine Klassen
oder Deine Notizen auch per Mail schicken. Das meiste von dem bisherigen
Excel-Sheet ist ja schon implementiert, ich muss also nur noch die
fehlenden Werte ergaenzen.

Robert

unread,
Jul 24, 2012, 8:08:41 AM7/24/12
to public-transport...@googlegroups.com
Woran haengts denn im Moment? Du kannst mir wie gesagt Deine Klassen
oder Deine Notizen auch per Mail schicken. Das meiste von dem bisherigen
Excel-Sheet ist ja schon implementiert, ich muss also nur noch die
fehlenden Werte ergaenzen.


Es hängt eigentlich gar nicht, oder höchstens an der Zeit. ;)  Ich habe gestern einen Fork auf GitHub angelegt und meinen Stand hochgeladen: https://github.com/rovo89/public-transport-enabler-fork/blob/hafas-binary-new/Hafas.java (neue Branch, damit ich ggf. Änderungen von dir abholen kann ohne direkt in Konflikte zu laufen). Allerdings fällt mir gerade auf, dass ich ein paar weitere Korrekturen noch nicht gepusht habe.

Wenn du dir die Datei ansiehst, siehst du ja, dass ich nicht auf einem InputStream arbeite, sondern auf einem Array (hier noch byte, lokal habe ich das schon auf char umgestellt). Ich finde das deutlich übersichtlicher, da man nicht auf eine bestimmte Reihenfolge der Aufrufe angewiesen ist (während sich die Leseposition im InputStream logischerweise beim Lesen verändert). Daher hatte ich dann noch angefangen, eine neue Klasse für eine Binary-Datei anzulegen, die z.B. den Puffer mit dem Dateiinhalt, aber auch einmal bestimmte Pointer enthält. Dadurch geht innerhalb dieser Klasse der Zugriff einfacher und AbstractHafasProvider.java wird nicht so aufgebläht. Zudem ist damit das Parsen der Datei unabhängig vom Füllen der DTOs. Innerhalb dieser Klasse habe ich dann für die Verbindungen, Teilstrecken und Zwischenhalte jeweils Unterklassen angelegt, die somit gleich den richtigen Kontext haben.

Da ich damit nur so halb fertig geworden bin, habe ich das noch nicht committed. Sollte aber denke ich heute Abend klappen, zumindest für die Standardfälle. Dann kannst du dir ansehen, ob die diese Trennung ebenfalls sinnvoll findest.


Noch eine Frage zu den Linien. Dieses Feld enthält meist mehrere Leerzeichen (z.B. "STR      2"). Ist dir das schonmal untergekommen? In parseLineAndType() gibt es z.B. eine Ersetzung von Whitespace. Aber da es eine Vielfalt von ähnlichen Funktionen gibt, bin ich mir nicht sicher, welche ich verwenden soll.


Und außerdem ist mir aufgefallen, dass die Verkehrsnetze in Öffi ja scheinbar einzelne Module sind, oder liege ich da falsch? Kann ich die neuen Methoden dort irgendwie zum Testen einbinden?

Andreas Schildbach

unread,
Jul 24, 2012, 12:02:36 PM7/24/12
to public-transport...@googlegroups.com
On 07/24/2012 02:08 PM, Robert wrote:

> Woran haengts denn im Moment? Du kannst mir wie gesagt Deine Klassen
> oder Deine Notizen auch per Mail schicken. Das meiste von dem
> bisherigen
> Excel-Sheet ist ja schon implementiert, ich muss also nur noch die
> fehlenden Werte ergaenzen.
>
> Wenn du dir die Datei ansiehst, siehst du ja, dass ich nicht auf einem
> InputStream arbeite, sondern auf einem Array (hier noch byte, lokal habe
> ich das schon auf char umgestellt). Ich finde das deutlich
> übersichtlicher, da man nicht auf eine bestimmte Reihenfolge der Aufrufe
> angewiesen ist (während sich die Leseposition im InputStream
> logischerweise beim Lesen verändert).

Ich habe das so gemacht, weil ich am Anfang des Streams keine
Gesamtlänge gefunden habe.

Und ich fands auch gar nicht so unelegant, insbesondere weil ja vieles
in dem Format relativ adressiert scheint.

> Sollte aber denke ich heute Abend klappen, zumindest für die
> Standardfälle. Dann kannst du dir ansehen, ob die diese Trennung
> ebenfalls sinnvoll findest.

Gerne.

> Noch eine Frage zu den Linien. Dieses Feld enthält meist mehrere
> Leerzeichen (z.B. "STR 2"). Ist dir das schonmal untergekommen?

Das ist fuer Hafas ganz normal. Du findest diese "Schreibweise" auch auf
manchen Webseiten von denen.

Normalerweise baue ich in meine Regexp's Patterns ein, die beliebig
viele Whitespaces als Trennung zwischen Linien-Typ und Linien-Nummer
erlauben.

> In
> parseLineAndType() gibt es z.B. eine Ersetzung von Whitespace. Aber da
> es eine Vielfalt von ähnlichen Funktionen gibt, bin ich mir nicht
> sicher, welche ich verwenden soll.

Ja, da ist leider einiges an Chaos. Ich muss das mal aufraeumen.

Fuer unseren Fall rufst Du am besten

Line line = parseLineWithoutType(lineStr);

auf. In dem zurueckgegebenen Line-Object steckt dann alles relevante drin.

> Und außerdem ist mir aufgefallen, dass die Verkehrsnetze in Öffi ja
> scheinbar einzelne Module sind, oder liege ich da falsch? Kann ich die
> neuen Methoden dort irgendwie zum Testen einbinden?

Schau Dir mal auf dem Branch hafas-binary den NasaProvider an, um den
gehts ja konkret. Dieser nutzt in queryConnections eine (neue) Methode
im AbstractHafasProvider.queryConnectionsBinary, die kennst Du
vermutlich schon. Du koenntest jetzt Deine Variante danebenstellen, z.B.
queryConnectionsBinary2. Dann koennte man entweder die eine oder die
andere Methode zum Parsen nehmen.

Robert

unread,
Jul 25, 2012, 9:21:39 AM7/25/12
to public-transport...@googlegroups.com

So, ich bin jetzt schon recht weit gekommen. Ich habe noch gute 2 Stunden investiert um herauszufinden, wie genau ich an das Datum einer Verbindung komme (insbesondere wenn es Verbindungen gibt, die erst nach Mitternacht beginnen). Das ist in der Tat eine Bitmaske, aber mit ein paar Besonderheiten, die selbst mit dekompiliertem Code schwer nachzuvollziehen waren. An dieser Stelle wird im Originalcode auch das Feld "Reisedatum + 30 Tage" gebraucht.

https://github.com/rovo89/public-transport-enabler-fork/blob/hafas-binary-new/enabler/src/de/schildbach/pte/HafasBinaryFile.java
https://github.com/rovo89/public-transport-enabler-fork/blob/hafas-binary-new/enabler/src/de/schildbach/pte/AbstractHafasProvider.java#L1420

Was noch fehlt sind die Zwischenhalte und Fehlerbehandlung.


> Und außerdem ist mir aufgefallen, dass die Verkehrsnetze in Öffi ja
> scheinbar einzelne Module sind, oder liege ich da falsch? Kann ich die
> neuen Methoden dort irgendwie zum Testen einbinden?

Schau Dir mal auf dem Branch hafas-binary den NasaProvider an, um den
gehts ja konkret. Dieser nutzt in queryConnections eine (neue) Methode
im AbstractHafasProvider.queryConnectionsBinary, die kennst Du
vermutlich schon. Du koenntest jetzt Deine Variante danebenstellen, z.B.
queryConnectionsBinary2. Dann koennte man entweder die eine oder die
andere Methode zum Parsen nehmen.

Achso, ich habe jetzt die vorhandene Methoden ersetzt. Aber dank Git kann man das ja einfach zurückholen. ;)

Ich meinte auch eigentlich, ob ich den aktuellen Stand in Öffi einbinden und dort testen kann. Die toString()-Methoden bieten ja nur einen ganz groben Überblick, also habe erstmal eine eigene Testklasse angelegt:
https://github.com/rovo89/public-transport-enabler-fork/blob/hafas-binary-new/enabler/test/de/schildbach/pte/TestHafasBinary.java
Dort wird eine lokal gespeicherte Verbindung analysiert und detailliert ausgegeben. Das zeigt auch, dass der Parser unabhängig von sonstigen Klassen ist, also kann man ihn ggf. auch anderweitig verwenden.

Es sah halt so aus, als würden die Provider dynamisch geladen, da u.a. eine Downloadgröße angegeben ist. Aber das scheint ja nicht der Fall zu sein, da ich die Klassen im APK gefunden habe. Ich nehme an, du hast nicht vor, den restlichen Quellcode zugänglich zu machen, oder? Das wäre natürlich das einfachste. Aber ich habe ein Framework für Android entwickelt, mit dem ich Code zur Laufzeit verändern kann. Eigentlich ist das eher für ROM-Tweaks gedacht, aber damit sollte ich die neue Klasse einschleusen können. ;) Dann werde ich mir auch mal den BahnProvider ansehen. Dort wird ja momentan die Mobilseite geparst, aber h2g-direct=11 funktioniert auch wunderbar. Ich habe die Hoffnung, darüber die Zwischenhalte integrieren zu können, die der Grund waren, weshalb ich hier überhaupt reingeschaut habe.

Andreas Schildbach

unread,
Jul 25, 2012, 9:54:00 AM7/25/12
to public-transport...@googlegroups.com
On 07/25/2012 03:21 PM, Robert wrote:

> So, ich bin jetzt schon recht weit gekommen. Ich habe noch gute 2
> Stunden investiert um herauszufinden, wie genau ich an das Datum einer
> Verbindung komme (insbesondere wenn es Verbindungen gibt, die erst nach
> Mitternacht beginnen). Das ist in der Tat eine Bitmaske, aber mit ein
> paar Besonderheiten, die selbst mit dekompiliertem Code schwer
> nachzuvollziehen waren. An dieser Stelle wird im Originalcode auch das
> Feld "Reisedatum + 30 Tage" gebraucht.

Vielen Dank fuer diese Muehen! Ich hab mir deinen Code angesehen und
daraus die Info extrahiert, wie man an die Attribute fuer Verbindungen
und Parts kommt. Damit hab ich eben mal ne neue Öffi-Version gebaut,
damit die ganzen Leipziger nicht weiter total auf dem Trockenen sitzen.

> Was noch fehlt sind die Zwischenhalte und Fehlerbehandlung.

Zwischenhalte sind in meinem Code fast fertig. Es tritt manchmal ein
Overflow auf, den Fehler werde ich jetzt suchen.

> Ich meinte auch eigentlich, ob ich den aktuellen Stand in Öffi einbinden
> und dort testen kann. Die toString()-Methoden bieten ja nur einen ganz
> groben Überblick, also habe erstmal eine eigene Testklasse angelegt:
> https://github.com/rovo89/public-transport-enabler-fork/blob/hafas-binary-new/enabler/test/de/schildbach/pte/TestHafasBinary.java
> Dort wird eine lokal gespeicherte Verbindung analysiert und detailliert
> ausgegeben. Das zeigt auch, dass der Parser unabhängig von sonstigen
> Klassen ist, also kann man ihn ggf. auch anderweitig verwenden.

Der ganze public-transport-enabler ist so gedacht, dass man ihn in
anderen Projekten verwenden kann. Eigentlich sehe ich keinen Sinn darin,
innerhalb dessen nochmal einen Teil unabhaengig verwendbar zu machen.

> Es sah halt so aus, als würden die Provider dynamisch geladen, da u.a.
> eine Downloadgröße angegeben ist. Aber das scheint ja nicht der Fall zu
> sein, da ich die Klassen im APK gefunden habe. Ich nehme an, du hast
> nicht vor, den restlichen Quellcode zugänglich zu machen, oder?

Nein, leider beides nicht. Die Downloadgroesse ich eine statische Datei
mit Haltestellen/Koordinaten, damit man die auch offline verfuegbar hat.

> Dann werde ich mir auch mal den BahnProvider
> ansehen. Dort wird ja momentan die Mobilseite geparst, aber
> h2g-direct=11 funktioniert auch wunderbar. Ich habe die Hoffnung,
> darüber die Zwischenhalte integrieren zu können, die der Grund waren,
> weshalb ich hier überhaupt reingeschaut habe.

Ja, darauf freue ich mich auch schon wie ein Schnitzel. Der BahnProvider
ist wirklich ein pita, und allein die Frage nach der Richtung der Linie
kommt am Tag mehrmals. Wundert mich, dass die mobile Webseite das immer
noch nicht eingebaut hat.

Es wird noch einige weitere Hafas-Server geben, die h2g-direct koennen.
Moeglicherweise einfach jeder.

Ich habe mich gerade an queryMoreConnections versucht (auf der Webseite:
frühere/spätere Verbindungen). Im Moment scheitere ich noch daran, die
korrekte URL zusammenzubauen. Der ident-Parameter ist ja klar, aber wie
muss die seqnr lauten? Meinst Du, Du koenntest das irgendwie aus dem
Code rekonstruieren?

Andreas Schildbach

unread,
Jul 25, 2012, 11:29:32 AM7/25/12
to public-transport...@googlegroups.com
On 07/25/2012 03:54 PM, Andreas Schildbach wrote:

> Zwischenhalte sind in meinem Code fast fertig. Es tritt manchmal ein
> Overflow auf, den Fehler werde ich jetzt suchen.

Dieses Problem ist jetzt behoben, es scheint jetzt einwandfrei zu
funktionieren.

Robert

unread,
Jul 25, 2012, 12:46:35 PM7/25/12
to public-transport...@googlegroups.com

Zwischenhalte sind in meinem Code fast fertig. Es tritt manchmal ein
Overflow auf, den Fehler werde ich jetzt suchen.

In der Standalone-Version sind die auch schon fertig, es war dann gestern nur zu spät, das noch zu migrieren.

Der ganze public-transport-enabler ist so gedacht, dass man ihn in
anderen Projekten verwenden kann. Eigentlich sehe ich keinen Sinn darin,
innerhalb dessen nochmal einen Teil unabhaengig verwendbar zu machen.

Unabhängig in dem Fall eher von externen Libraries für XML und JSON. Aber das ist auch definitiv nicht der Fokus. Die wichtigsten Gründe für die Trennung sind:
1. Alles, was für das Parsen der Binärdateien notwendig ist, ist an einem Platz --> die Hauptklasse bleibt übersichtlicher.
2. Die Ermittlung der einzelnen Werte sind einzelne Methoden ausgelagert, so findet man sie deutlich schneller.
3. Der Kontext ist über die Instanz(en) vorhanden und muss nicht immer mitgegeben werden. Die Unterklassen heißen zwar mangels besseren Namens gleich wie die DTOs haben aber eine ganz andere Funktion, nämlich das Ermitteln der Werte in ihrem Kontext.
4. Es können mehr Werte angeboten werden als public-transport-enabler selbst benötigt. Z.B. können für die Stops sowohl Plan- als auch Realdaten ermittelt werden, und zwar für Ankunft und Abfahrt. Das DTO unterstützt aber nur eine Zeit, ein Gleis und natürlich den Ort. Also baue ich die Sachen, die man mal brauchen könnte, in HafasBinaryFile ein und rufe dann nur die verwendeten Daten im Provider ab. Da dort deutlich weniger Code ist, ist transparenter, welche Daten wo einfließen.
5. Es ist stärker an den Originalcode angelehnt. Ich habe bei der Migration von Standalone in den Provider schon einige Sachen optimiert, aber prinzipiell sollte das Verhalten recht originalgetreu und damit hoffentlich sicherer sein.
 
Letztendlich haben wir beide etwas implementiert, in das wir viel Zeit investiert haben und von dem wir überzeugt sind, dass der Ansatz eigentlich zu gut ist, um ihn wegzuschmeißen. Vielleicht überzeugen dich ja trotzdem die genannten Argumente. ;)

Nein, leider beides nicht. Die Downloadgroesse ich eine statische Datei
mit Haltestellen/Koordinaten, damit man die auch offline verfuegbar hat.

Aber offline kann man doch eh nicht suchen, oder wofür ist das?

Ich habe mich gerade an queryMoreConnections versucht (auf der Webseite:
frühere/spätere Verbindungen). Im Moment scheitere ich noch daran, die
korrekte URL zusammenzubauen. Der ident-Parameter ist ja klar, aber wie
muss die seqnr lauten? Meinst Du, Du koenntest das irgendwie aus dem
Code rekonstruieren?

Ich werds versuchen. Wobei ich den Sequenzparameter für gar nicht so entscheidend betrachtet hatte, da der vielleicht einfach hochgezählt werden kann. Wichtiger ist "&ld=9543" (oder ähnlich). Den hast du doch auch noch nicht dabei, oder? Schau mal in mein Coding, da ist das schon getestet.

Robert

unread,
Jul 25, 2012, 5:26:38 PM7/25/12
to public-transport...@googlegroups.com
So. Zwischenhalte sind integriert ebenso queryMoreConnections(). Ich habe es hinbekommen, die entsprechenden Klassen zur Laufzeit zu überschreiben und konnte es somit schon testen. Klappt gut. :)

Als nächstes habe ich mir dann die Bahn vorgenommen. Ich habe die Wahlmöglichkeit zwischen Binär und XML in die abstrakte Klasse eingebaut und dann angefangen im BahnProvider zu löschen. Jetzt ist kaum noch Code übrig; über die Hälfte ist gelöscht und der Rest ist teilweise ziemlich gestreckt. Und das tolle daran ist: Als Nebeneffekt funktionieren die Zwischenhalte und die Richtungsangaben. Herrlich. :) In ein paar Fällen crasht die Anzeige allerdings in ConnectionDetailsActivity$ConnectionPartsListAdapter:936, und zwar wenn bei einem Zwischenhalt kein Datum festgelegt ist. Das ist z.B. zwischen Berlin und Frankfurt bei den "CNL"-Zügen der Fall (und auf der Seite nachvollziehbar). Ich wüsste keinen sinnvollen Wert, den ich in einem solchen Fall übergeben könnte, daher sehe ich den Korrekturbedarf bei dir (die Zeitanzeige kann ja leer bleiben und nur der Ort angezeigt werden).

Dazu kommt noch, dass jetzt die Stationen als solche erkannt werden, während sie vorher wohl nur Text waren. Ich sehe das vorteilhaft, weil dadurch der Favoritenbutton in der Actionbar freigeschaltet wird. Aber die Insa-Unittest schlagen wegen uneindeutigen Ergebnissen fehl und man wird gefragt was man meint, wenn man noch alte Verbindungen gespeichert hat oder die Station nicht aus den Vorschlägen auswählt. Wobei ich das durchaus als Feature sehe.

Andreas Schildbach

unread,
Jul 25, 2012, 7:52:26 PM7/25/12
to public-transport...@googlegroups.com
Wow, jetzt geht's ja wirklich Schlag auf Schlag. Sehr beeindruckend, das
mit dem Austauschen der Klassen zur Laufzeit. Und im Öffi-Code scheinst
Du Dich schon besser auszukennen als ich (-:

Ja, der Kahlschlag in den Providern kann beeindruckend sein. Übrigens
können wir jetzt glaub ich die komplette Methode getConnectionDetails()
überall löschen; die Bahn war IMHO der einzige Provider der dieses
Konzept noch benoetigt hat. Das vereinfacht auch auf Öffi-Seite einiges.

Zusaetzlich von den von Dir genannten Vorteilen kann ich dann auch die
Maps-Integration freischalten.

Den Fehler schaue ich mir an, in der Tat ist es besser einfach nichts
anzuzeigen als sich einen Wert aus der Nase zu ziehen. Aber komisch ists
schon, dass es keinen Wert gibt. Bei Zwischenhalten gibt es ja
normalerweise sowohl Ankunfts- als auch Abfahrtszeit. Ist beides nicht
gesetzt?

Dennoch wuerde ich den ganzen Spass noch ein bisschen in Leipzig testen,
und den Rollout auf Deutschland noch ein bisschen verschieben. Ich
moechte einigermassen sichergehen, dass es keine groben Fehler mehr gibt.

Robert

unread,
Jul 26, 2012, 6:56:57 AM7/26/12
to public-transport...@googlegroups.com

Wow, jetzt geht's ja wirklich Schlag auf Schlag. Sehr beeindruckend, das
mit dem Austauschen der Klassen zur Laufzeit. Und im Öffi-Code scheinst
Du Dich schon besser auszukennen als ich (-:

Ne ne, ich habe halt den Dump bekommen und gemeldet. Aber viel musste ich noch nicht im Öffi-Code nachsehen. ;)
Das Austauschen der Klassen ist hilfreich, allerdings nicht massentauglich. Ich habe das als Modul für mein Framework gebaut, wobei ich den Classpath für Öffi erweitere um ein neues APK, in das ich nur die geänderten Klassen eingebunden habe. Das funktioniert allerdings auch nur, wenn ich den Dalvik-Verfier ausschalte... für mich ist es passend so, aber es lässt sich nicht so einfach weitergeben.

Ja, der Kahlschlag in den Providern kann beeindruckend sein. Übrigens
können wir jetzt glaub ich die komplette Methode getConnectionDetails()
überall löschen; die Bahn war IMHO der einzige Provider der dieses
Konzept noch benoetigt hat. Das vereinfacht auch auf Öffi-Seite einiges.

Daran hatte ich auch schon gedacht, aber es sollten wohl zuerst alle Referenzen auf die Methode entfernt sein. Im Unittest hatte ich das schon gemacht, aber bei Öffi ging das natürlich nicht, daher habe ich die Methode drin gelassen.

Den Fehler schaue ich mir an, in der Tat ist es besser einfach nichts
anzuzeigen als sich einen Wert aus der Nase zu ziehen. Aber komisch ists
schon, dass es keinen Wert gibt. Bei Zwischenhalten gibt es ja
normalerweise sowohl Ankunfts- als auch Abfahrtszeit. Ist beides nicht
gesetzt?

Ich kann nochmal nachsehen.. aber auch auf der Bahnseite stehen keine Zeiten dabei. Teilweise sind aber die Gleise angegeben. Schon eine merkwürdige Kombination. 
 
Dennoch wuerde ich den ganzen Spass noch ein bisschen in Leipzig testen,
und den Rollout auf Deutschland noch ein bisschen verschieben. Ich
moechte einigermassen sichergehen, dass es keine groben Fehler mehr gibt.

Definitiv! Ich finde, der aktuelle Stand ist schon nicht schlecht, aber gerade die Fehlerbehandlung muss noch erweitert werden.

Hast du eigentlich mal meine Implementierung ausprobiert? Ich habe gesehen, dass du noch einige meiner Korrekturen übernommen hast. Bis auf die elementare Fehlerbehandlung (wenn das erste Byte ungleich 6 ist) und die Verwendung von splitPlaceAndName müsste ich auch alles drin haben, plus vielleicht die ein oder andere Prüfung und Originalcode-ähnlichere Verarbeitung (mit weniger Annahmen) mehr. Ich hatte es ja schon angedeutet, so ganz glücklich bin ich mit der momentanen Situation nicht, mit zwei unterschiedlichen Ansätzen die gleichen Sachen zu implementieren.

Im Übrigens, ist dir schonmal eine "Plankennung" für Verbindungsdaten untergekommen? Ich versuche noch, die restlichen Daten zu deuten, und einer der Werte ist ein String, der in einer Ausgabe zusammen mit dieser Bezeichnung verwendet wird. Ich vermute aber, dass es nichts entscheidendes ist.

Andreas Schildbach

unread,
Jul 26, 2012, 7:33:23 AM7/26/12
to public-transport...@googlegroups.com
On 07/26/2012 12:56 PM, Robert wrote:

> Den Fehler schaue ich mir an, in der Tat ist es besser einfach nichts
> anzuzeigen als sich einen Wert aus der Nase zu ziehen. Aber komisch
> ists
> schon, dass es keinen Wert gibt. Bei Zwischenhalten gibt es ja
> normalerweise sowohl Ankunfts- als auch Abfahrtszeit. Ist beides nicht
> gesetzt?
>
>
> Ich kann nochmal nachsehen.. aber auch auf der Bahnseite stehen keine
> Zeiten dabei. Teilweise sind aber die Gleise angegeben. Schon eine
> merkwürdige Kombination.

Ich habe das Problem auf Öffi-Seite gerade gefixed - soll ich Dir ne
.apk-Datei schicken? Ich vermute, die Bahn will sich einfach nicht so
richtig festlegen, wann der Nachtzug ne Stunde im Güterbahnhof rumsteht.
Denn teilweise stehen die Nachtzüge extra rum, damit die Leute länger
schlafen können.

> Definitiv! Ich finde, der aktuelle Stand ist schon nicht schlecht, aber
> gerade die Fehlerbehandlung muss noch erweitert werden.

In diesem Zusammenhang wäre es interessant zu wissen, ob die
h2g-Schnittstelle auch eine "disambiguation" vornimmt, oder ob
grundsaetzlich alles eindeutig eingegeben werden muss.

Falls man z.B. sowas nichtssagendes wie "Platz" als Startort eingibt
(ohne ID, als LocationType.ANY), kommt ja ein Fehler. Die Frage ist, ob
es irgendwo Vorschlagslisten gibt, und zwar ggf. getrennt fuer Start,
Ziel und 0..x Vias.

Dann gibt es verschiedene Fehler, z.B. "Datum nicht innerhalb der
Fahrplanperiode" oder "Start und Ziel zu nah beieinander". In der
Methode AbstractHafasProvider.queryConnections() gibt es eine Liste
davon, mit Codes - evtl. finden wir die Codes ja im Binary wieder?

> Hast du eigentlich mal meine Implementierung ausprobiert?

Ich habe sie nicht laufenlassen, aber eifrig studiert. Meine erste Frage
ist noch offen (evtl. habe ich die Antwort uebersehen): Woher weisst Du,
wieviele Bytes Du vom Stream lesen musst? - eine Gesamtzahl scheint es
nicht zu geben.

> Ich hatte es ja schon
> angedeutet, so ganz glücklich bin ich mit der momentanen Situation
> nicht, mit zwei unterschiedlichen Ansätzen die gleichen Sachen zu
> implementieren.

Ich gehe davon aus, dass die Ansaetze auf Dauer konvergieren. Und es
fuer die Validierung der Korrektheit, ist es gar nicht schlecht, zwei
Ansaetze unabhaengig zu entwickeln (die NASA - in diesem Fall meine ich
die Weltraumbehörde - macht das auch so).

> Im Übrigens, ist dir schonmal eine "Plankennung" für Verbindungsdaten
> untergekommen? Ich versuche noch, die restlichen Daten zu deuten, und
> einer der Werte ist ein String, der in einer Ausgabe zusammen mit dieser
> Bezeichnung verwendet wird.

Der Name sagt mir nichts. Wie sehen solche Plankennungen denn aus? Und
haengen sie an einer Verbindung, oder einem Part?

Uebrigens waere es auch mal interessant zu erforschen, was sich so
aendert wenn man die Zahl 11 hinter "h2g-direct" variiert.

Robert Vollmer

unread,
Jul 26, 2012, 9:19:55 AM7/26/12
to public-transport...@googlegroups.com
> Ich habe das Problem auf Öffi-Seite gerade gefixed - soll ich Dir ne
> .apk-Datei schicken?

Gerne. Hast du über die Gruppe meine Mailadresse bekommen?

> In diesem Zusammenhang wäre es interessant zu wissen, ob die
> h2g-Schnittstelle auch eine "disambiguation" vornimmt, oder ob
> grundsaetzlich alles eindeutig eingegeben werden muss.
>
> Falls man z.B. sowas nichtssagendes wie "Platz" als Startort eingibt
> (ohne ID, als LocationType.ANY), kommt ja ein Fehler. Die Frage ist, ob
> es irgendwo Vorschlagslisten gibt, und zwar ggf. getrennt fuer Start,
> Ziel und 0..x Vias.
>
> Dann gibt es verschiedene Fehler, z.B. "Datum nicht innerhalb der
> Fahrplanperiode" oder "Start und Ziel zu nah beieinander". In der
> Methode AbstractHafasProvider.queryConnections() gibt es eine Liste
> davon, mit Codes - evtl. finden wir die Codes ja im Binary wieder?

Ich würde erstmal schauen, wie die Originalapps das machen, am
einfachsten mal mit tcpdump mitschneiden, welche Anfragen die in
solchen Fällen senden.
Statuscodes gibt es durchaus, ich habe aber noch nicht genauer
geforscht, welche Werte wann auftreten.
Im Code hatte ich ein paar Sachen in der Richtung gefunden:
https://github.com/rovo89/public-transport-enabler-fork/blob/hafas-binary-new/enabler/src/Hafas.java#L67

Die Felder ab Position 4 und 16 im erweiterten Header scheinen Werte
in der Richtung zu enthalten.

>> Hast du eigentlich mal meine Implementierung ausprobiert?
>
> Ich habe sie nicht laufenlassen, aber eifrig studiert. Meine erste Frage
> ist noch offen (evtl. habe ich die Antwort uebersehen): Woher weisst Du,
> wieviele Bytes Du vom Stream lesen musst? - eine Gesamtzahl scheint es
> nicht zu geben.

Ganz einfach, bis zum Ende. Dafür konnte ich deine vorhandenen
Funktionen verwenden:
char[] buf = ParserUtils.scrape(uri, null, ISO_8859_1,
null).toString().toCharArray();

Innerhalb scrape() wird copy() für den GZIPInputStream aufgerufen, was
bis zum Ende des Streams liest. Das ist also genau so wie bei einer zu
parsenden HTML-Seite.

>
>> Ich hatte es ja schon
>> angedeutet, so ganz glücklich bin ich mit der momentanen Situation
>> nicht, mit zwei unterschiedlichen Ansätzen die gleichen Sachen zu
>> implementieren.
>
> Ich gehe davon aus, dass die Ansaetze auf Dauer konvergieren. Und es
> fuer die Validierung der Korrektheit, ist es gar nicht schlecht, zwei
> Ansaetze unabhaengig zu entwickeln (die NASA - in diesem Fall meine ich
> die Weltraumbehörde - macht das auch so).

Naja, aber das Parsen von Bahnverbindungen ist ja keine Raketenwissenschaft. ;)

Ich finde, das birgt eher die Gefahr, dass wir in komische Fehler
laufen, die der andere schon behoben hat.
Z.B. sehe ich bei dir keine Korrektur des Datums, wenn in einer
Abfrage Verbindungen vorkommen, die erst
am nächsten Tag beginnen. Oder Behandlung des Spezialfalls, dass es
zwei Fußwege hintereinander gibt,
von denen einer das Attribut "Hide" hat (Öffi crasht offensichtlich in
der Situation und es sähe auch komisch aus).
Und wenn etwas übernehmen möchte, muss man sehr genau aufpassen, weil
eben die Ansätze unterschiedlich
sind und bei mir in bestimmten Situationen "null" zurückkommt und bei
dir vielleicht eine leere Zeichenkette.

Es ist sicherlich sehr gut, die Änderungen genau anzugucken, zu
überlegen ob das eleganter/sicherer geht
und ob es vielleicht Fälle gibt, in denen es nicht funktioniert. Aber
gerade das wird durch die grundlegend
verschiedenen Ansätze erschwert, weil es eben nicht nur darum geht, ob
man jetzt von einem Stream oder
aus einem Array liest, sondern sich auch andere Details unterscheiden.

Ich denke, die Qualität der Umsetzung würde davon profitieren, wenn
wir uns vielleicht irgendwo in der Mitte treffen könnten.
Wenn dir viel an die Verwendung des Streams gelegen ist, kann ich
meine Klasse auch darauf umbauen (auch wenn es
zur Laufzeit wohl keinen Unterschied macht, da der BufferedInputStream
intern auch ein Array verwenden dürfte, das er
sogar dynamisch erweitern muss). Ich helfe ja gerne, Öffi weiter zu
verbessern, denn ich nutze es sehr gerne, aber
so ist es unnötig aufwändig. Im Idealfall können Korrekturen 1:1
ausgetauscht werden.

>> Im Übrigens, ist dir schonmal eine "Plankennung" für Verbindungsdaten
>> untergekommen? Ich versuche noch, die restlichen Daten zu deuten, und
>> einer der Werte ist ein String, der in einer Ausgabe zusammen mit dieser
>> Bezeichnung verwendet wird.
>
> Der Name sagt mir nichts. Wie sehen solche Plankennungen denn aus? Und
> haengen sie an einer Verbindung, oder einem Part?

Das Problem ist: Ich habe bisher nur den Fall gesehen, dass der Wert
"---" ist. Wenn ich wüsste, was der Wert bedeutet, könnte ich
vielleicht Situationen erzeugen, in denen das Feld gefüllt ist.

> Uebrigens waere es auch mal interessant zu erforschen, was sich so
> aendert wenn man die Zahl 11 hinter "h2g-direct" variiert.

Ja, vielleicht bekommen wir darüber weitere Hinweise, wofür eine
Felder (ggf. aus historischen Gründen) stehen. Denn mit h2g-direct=1
kommt ein Ergebnis zurück, das die Datenversion 5 hat (steht im ersten
Feld), aber trotzdem die Verbindung enthält. Also sollte die
Fehlerabfrage keinesfalls über dieses Byte gehen. Allgemein ist das
aber auch ein guter Testfall, um die Fehlertoleranz und Kompatibilität
der Implementierungen zu überprüfen. Übrigens kam mir gerade der
Gedanke, dass die 11 ja nicht zwangsläufig eine Dezimalzahl sein muss.
Vielleicht ist es auch eine Bitmaske?

Andreas Schildbach

unread,
Jul 26, 2012, 12:35:30 PM7/26/12
to public-transport...@googlegroups.com
On 07/26/2012 03:19 PM, Robert Vollmer wrote:

> Ich w�rde erstmal schauen, wie die Originalapps das machen, am
> einfachsten mal mit tcpdump mitschneiden, welche Anfragen die in
> solchen F�llen senden.

Ja, das habe ich vor und werde das naechste Woche anpacken.

> Ganz einfach, bis zum Ende. Daf�r konnte ich deine vorhandenen
> Funktionen verwenden:
> char[] buf = ParserUtils.scrape(uri, null, ISO_8859_1,
> null).toString().toCharArray();

Ein bisschen komisch ist, dass Du ein Byte-Array als char[] einliest.
Diese Methode war eigentlich nur fuers Einlesen von Webseiten (=Text)
gedacht. Wundert mich, dass es trotzdem funktioniert.

> Innerhalb scrape() wird copy() f�r den GZIPInputStream aufgerufen, was
> bis zum Ende des Streams liest. Das ist also genau so wie bei einer zu
> parsenden HTML-Seite.

Bei geparstem XML z.B. wird einfach abgebrochen, sobald alle Werte da
sind. Das ist halt der Vorteil eines Streams, aber ich gebe zu, das ist
wohl eher theoretisch.

> Ich finde, das birgt eher die Gefahr, dass wir in komische Fehler
> laufen, die der andere schon behoben hat.
> Z.B. sehe ich bei dir keine Korrektur des Datums, wenn in einer
> Abfrage Verbindungen vorkommen, die erst
> am n�chsten Tag beginnen.
> Oder Behandlung des Spezialfalls, dass es
> zwei Fu�wege hintereinander gibt,

Beides war schon auf meinem Schirm, Malte hatte ja schon auf das Problem
hingewiesen. Inzwischen behoben.

> Und wenn etwas �bernehmen m�chte, muss man sehr genau aufpassen, weil
> eben die Ans�tze unterschiedlich
> sind und bei mir in bestimmten Situationen "null" zur�ckkommt und bei
> dir vielleicht eine leere Zeichenkette.

Ja, genau diese Feinheiten sehe ich auch als Problem. Ich wollte Dich
schon ueberreden, im Falle von "unbekannt" immer null (Object) oder 0
(int/short) zurueckzugeben. Leerstrings, "---" etc. sind i.d.R. keine
gute Idee.

Es gibt noch eine Reihe weiterer Dinge, die ich anmerken wuerde.
Vielleicht das wichtigste, dass Du zusaetzlich zu den DTO nochmal alle
Objecte in diese Parser-Objekte wrappst. Unter Android ist
Objekt-Instantiierung nochmal viel teurer als bei normalem Java. Daher
habe ich schon vor, ueber meinen Code nochmal optimierend drueber zu
gehen, bevor ich alles auf master merge.

Die Umstellung von Stream auf Byte-Array koennte ich mir vorstellen,
auch wenn ich schon einen Horror vor dem manuellen Hochzaehlen von
Pointern habe.

Wie gesagt, wenn wir durch alle der Punkte durch sind, glaube ich sind
wir ohnehin konvergiert... (-:

>>> Im �brigens, ist dir schonmal eine "Plankennung" f�r Verbindungsdaten
>>> untergekommen? Ich versuche noch, die restlichen Daten zu deuten, und
>>> einer der Werte ist ein String, der in einer Ausgabe zusammen mit dieser
>>> Bezeichnung verwendet wird.
>>
>> Der Name sagt mir nichts. Wie sehen solche Plankennungen denn aus? Und
>> haengen sie an einer Verbindung, oder einem Part?
>
> Das Problem ist: Ich habe bisher nur den Fall gesehen, dass der Wert
> "---" ist. Wenn ich w�sste, was der Wert bedeutet, k�nnte ich
> vielleicht Situationen erzeugen, in denen das Feld gef�llt ist.

Ich glaube, der String ist eigentlich als null zu interpretieren. Denn
der String-Index von "---" ist immer 0, so dass ich glaube auf die 0
kommts an und das "---" wurde nur eingefuegt um zu vermeiden dass
schlecht programmierter Code crashed.

>> Uebrigens waere es auch mal interessant zu erforschen, was sich so
>> aendert wenn man die Zahl 11 hinter "h2g-direct" variiert.
>
> �brigens kam mir gerade der
> Gedanke, dass die 11 ja nicht zwangsl�ufig eine Dezimalzahl sein muss.
> Vielleicht ist es auch eine Bitmaske?

Bitmaske ist ein heisser Tip.

Uebrigens habe ich grade mal ein paar andere Verkehrsnetz durchprobiert.
Zwei bisherige Problemfaelle, der BVG (Berlin) und VBN (Bremen) koennen
auch h2g-direct=11. Leider ist jedoch der Extension Header nur 0x2c
lang, wodurch es auf den ersten Blick keine Verbindungs-Attribute gibt.
Es muss wohl noch einen anderen Weg geben, die ConnectionId ("C0-0") zu
ermitteln.

Robert Vollmer

unread,
Jul 27, 2012, 10:01:43 AM7/27/12
to public-transport...@googlegroups.com
>> Ganz einfach, bis zum Ende. Dafür konnte ich deine vorhandenen
>> Funktionen verwenden:
>> char[] buf = ParserUtils.scrape(uri, null, ISO_8859_1,
>> null).toString().toCharArray();
>
> Ein bisschen komisch ist, dass Du ein Byte-Array als char[] einliest.
> Diese Methode war eigentlich nur fuers Einlesen von Webseiten (=Text)
> gedacht. Wundert mich, dass es trotzdem funktioniert.

Mich auch. ;) Ursprünglich habe ich auch mit einem Byte-Array
gearbeitet. Da war aber das Problem, dass byte ein Vorzeichen hat und
ich somit ein (D)Word nicht einfach zusammenaddieren konnte (wobei das
sehr einfach zu beheben ist). Und da es nun schon im Prinzip genau die
Methode zum kompletten Einlesen für char gibt, habe ich darauf
verzichtet, sie mit byte nochmal zu bauen.

> Ja, genau diese Feinheiten sehe ich auch als Problem. Ich wollte Dich
> schon ueberreden, im Falle von "unbekannt" immer null (Object) oder 0
> (int/short) zurueckzugeben. Leerstrings, "---" etc. sind i.d.R. keine
> gute Idee.

Da stimme ich dir zu (wobei ich "undefiniert" eher als -1 wählen
würde, um es von Werten abgrenzen zu können, die einfach nicht kleiner
als 0 sein können, siehe getFootwayDuration). Allerdings habe ich das
auch schon weitestgehend umgesetzt. Wo fehlt dir das denn noch?

>
> Es gibt noch eine Reihe weiterer Dinge, die ich anmerken wuerde.
> Vielleicht das wichtigste, dass Du zusaetzlich zu den DTO nochmal alle
> Objecte in diese Parser-Objekte wrappst. Unter Android ist
> Objekt-Instantiierung nochmal viel teurer als bei normalem Java. Daher
> habe ich schon vor, ueber meinen Code nochmal optimierend drueber zu
> gehen, bevor ich alles auf master merge.

Ich habe mal gelernt, dass in Java die Objekt-Instantiierung billiger
ist als man denken würde.
Unter Android kann ich es nicht sagen. Ich glaube eher nicht, dass
sich das in einem bemerkbaren Rahmen bewegt (insbesondere mit JIT). Es
macht halt die Methodennamen etwas kürzer und bringt Struktur in den
Code (und die finde ich durchaus wichtig). Aber gut, darauf könnte ich
verzichten, da ich letztendlich sowieso ziemlich viele der Werte
ermittle. Aber an einem hänge ich doch sehr, und zwar die
umschließende Klasse pro Datei. Du hast ja vorhin das Encoding
eingebaut und musstest den Wert durch alle Funktionen durchschleifen.
Natürlich darf es kein Instanzfeld sein, aber wenn man auf einige
Werte einfach zugreifen kann ist das schon von Vorteil. Denn dann kann
man auch einfacher Teile des Codes in Funktionen auslagern, das fehlt
mir bei dir doch sehr.

Ich könnte mir das so vorstellen, dass es jeweils eine Funktion zum
Erstellen der DTOs für Connection, Part und Stop gibt. Bei komplexeren
Berechnungen vielleicht nochmal Unterfunktionen. Damit wären wir uns
denke ich schon deutlich einiger. ;) Und ich habe mir für mein
Framework auch den Interpreter und die Abläufe dabei angesehen, der
Aufwand für Funktionsrufe ist wirklich ziemlich gering.

> Die Umstellung von Stream auf Byte-Array koennte ich mir vorstellen,
> auch wenn ich schon einen Horror vor dem manuellen Hochzaehlen von
> Pointern habe.

Naja, man muss das ja nicht nach jedem Wert hochzählen. Ich arbeite
öfters mit Pointern auf die "Struktur" und dazu relativen Offsets.
Streams haben halt den Nachteil, dass das Lesen eines Wertes
Nebeneffekte hat. So kann man nicht mal einfach etwas von einer
anderen Stelle lesen, sondern muss danach wieder zurückspringen.

> Wie gesagt, wenn wir durch alle der Punkte durch sind, glaube ich sind
> wir ohnehin konvergiert... (-:

Das kann durchaus sein. Ich kann ja auf der einen Seite mal meinen
Code etwas flacher machen (sprich die Unterklassen raus) und die DTOs
direkt dort erzeugen und auf der anderen Seite deinen Code in
Funktionen in einer einzigen neuen Klassen unterteilen und diese ein
Byte-Array (oder char? der Aufwand ist ähnlich) verwenden lassen.
Damit dürften dann jeweils die zwei größten "Mängel" (die mMn nicht
wirklich falsch sind, sondern einfach unterschiedliche Philosophien
sind) behoben sein und wir können sehen, welche Unterschiede noch
übrig sind. Meinst du, so können wir auf einen gemeinsamen Nenner
kommen?

> Ich glaube, der String ist eigentlich als null zu interpretieren. Denn
> der String-Index von "---" ist immer 0, so dass ich glaube auf die 0
> kommts an und das "---" wurde nur eingefuegt um zu vermeiden dass
> schlecht programmierter Code crashed.

Also dass es ein Zeichen für "nicht vorhanden" ist, ist denke ich
klar. Aber ich hätte die Annahmen "Index 0 => null" nicht gemacht. Wer
auch immer die API benutzt, bekommt nicht die 0 sondern "---" und muss
ggf. darauf reagieren. Daher habe ich das genauso umgesetzt und
vergleiche beim Normalisieren mit "---". Wenn das gefunden wird oder
die Zeichenkette leer ist (nach dem trim()), wird null zurückgegeben.

> Uebrigens habe ich grade mal ein paar andere Verkehrsnetz durchprobiert.
> Zwei bisherige Problemfaelle, der BVG (Berlin) und VBN (Bremen) koennen
> auch h2g-direct=11. Leider ist jedoch der Extension Header nur 0x2c
> lang, wodurch es auf den ersten Blick keine Verbindungs-Attribute gibt.
> Es muss wohl noch einen anderen Weg geben, die ConnectionId ("C0-0") zu
> ermitteln.
>

Es muss nicht. ;) Ich habe bei der Bahn mal die Abfrage mit h2g-direct
ohne Wert gemacht - da steht der String nicht mit drin. Ich habe die
Befürchtung, dass diese ID dort einfach nicht mitgeliefert wird. Wenn
du die nur zur Identitätsfeststellung brauchst, müsste aber auch ein
Hash (z.B. aus Abfahrtsorten und -zeiten der Teilverbindungen)
genügen, oder? Ich hatte schon die Idee, mal eine Abdeckungsanalyse zu
machen, also mal mitzuschreiben, welche Bytes bereits gelesen werden
und welche möglicherweise noch unbekannte Daten enthalten.

Ich habe mittlerweile herausgefunden, dass die Plankennung für den
persönlichen Fahrplan verwendet wird, den man sich herunterladen kann.
Dann sind auch andere Bytes gefüllt. Weiterhin habe ich schon die
Fehlercodes für einige Situationen identifizieren können.
Mehrdeutigkeit gibt es auch, aber ohne Hinweise darauf was mehrdeutig
ist (das Ergebnis bei mehrdeutigem Start/Ziel ist komplett gleich).
Die Bahnapp verwendet übrigens XML für die automatische
Vervollständigung, ich weiß nicht ob das noch mehr Daten liefert als
JSON.

Und noch eine Frage: Gibt es in Öffi eine Sortierung der Verbindungen
(für die Anzeige) oder wird erwartet, dass diese in zeitlich richtiger
Reihenfolge zurückgegeben werden? Wenn man Verbindungen vor/nach
Mitternacht hat, gibt es manchmal Sprünge in der Anzeige.

Malte Starostik

unread,
Jul 29, 2012, 7:55:07 PM7/29/12
to public-transport...@googlegroups.com
Hallo,

habe die Tabelle nochmal erweitert, die Attribute zu Verbindungen und Tarifangaben sollten damit klar sein. Und erst dann habe ich gesehen, dass sich hier ja so einiges getan hat :-) Also sorry für eh schon bekannte Infos.

Was die Reihenfolge der Verbindungen bei einem Tageswechsel angeht, scheint tatsächlich zu gelten:
Das Verbindungs-Array ist nur nach Uhrzeit sortiert, also im Fall eines Tageswechsels ist die Reihenfolge "falsch". Einerseits ist evtl. das letzte Feld der Einträge in der "Verkehrstage-Tabelle" geeignet, diesen Fall zu erkennen, zumindest kann damit anscheinend das Datum relativ zum Reisedatum ermittelt werden. Aber unabhängig davon sind auch die ConnectionId-Attribute in der Darstellungs-Reihenfolge, C0-0 ist die früheste Verbindung, aber eben nicht immer die erste im Array.

Dieser ganze Attribute (Key, Value)-Kram enthält einige Informationen, die m.E. deutlich weniger sorgfältig organisiert sind als die fest strukturierten Blöcke. Schon alleine, dass alles als String dargestellt wird, obwohl viele Angaben Zahlen sind. Dann gibt es Redundanzen (jede Tarifalternative referenziert die Fahrzeit als Stringdarstellung der Minutenzahl, und zwar wirklich in Minuten im Gegensatz zu der merkwürdigen Kodierung im binären Gegenpart, naja). Es gibt diverse Fahrzeugkategorien, die sich teils überschneiden, teils auch nicht. Sieht halt nach viel Kompatibilitäts-Wahrung zu anderen Versionen oder zwischen HAFAS und Netzbetreiber etc. aus, aber was soll's.

Mit verschiedenen Werten für h2g-direct zu spielen hatte ich auch vorgehabt, aber nie gemacht.

PS @Robert: wenn Du noch Schreibrechte willst/brauchst, kannste Dich gerne off-list melden.

PPS: Habe übrigens spaßenshalber mal den Traffic der INSA-iOS-App gesnifft, die macht natürlich wieder ganz andere Abfragen, irgendwas application/x-b-xml? Aber als in dem nicht gzip, aber vermutlich anders komprimierten BLOB nicht ein einziger String zu erkennen war, hab ich's auch schnell wieder sein gelassen.

Robert Vollmer

unread,
Jul 30, 2012, 2:28:59 AM7/30/12
to public-transport...@googlegroups.com
> Was die Reihenfolge der Verbindungen bei einem Tageswechsel angeht, scheint
> tatsächlich zu gelten:
> Das Verbindungs-Array ist nur nach Uhrzeit sortiert, also im Fall eines
> Tageswechsels ist die Reihenfolge "falsch". Einerseits ist evtl. das letzte
> Feld der Einträge in der "Verkehrstage-Tabelle" geeignet, diesen Fall zu
> erkennen, zumindest kann damit anscheinend das Datum relativ zum Reisedatum
> ermittelt werden. Aber unabhängig davon sind auch die ConnectionId-Attribute
> in der Darstellungs-Reihenfolge, C0-0 ist die früheste Verbindung, aber eben
> nicht immer die erste im Array.

Es ist der letzte Eintrag in der "Verkehrstage-Tabelle". Das ist wie
von dir vermutet eine Bitmaske, wobei die beiden Einträge davor auch
noch eine Rolle spielen.
Das habe ich durch Analyse der INSA-App herausgefunden, wobei die
Funktion dort zurückgibt, ob eine Verbindung an einem bestimmten Tag
stattfindet. Hier ist
meine Implementierung einer Funktion, die den ersten Verkehrstag ermittelt:
https://github.com/rovo89/public-transport-enabler-fork/blob/f3a59e98ca097c1585cede7f64c2e54398b6dc6a/enabler/src/de/schildbach/pte/util/HafasBinaryFile.java#L294

Wenn man sich in der Bahn-App einen persönlichen Abfahrtsplan
erstellen lässt, bekommt man eine Datei im gleichen Format (allerdings
mit älterer Header-Version).
Ich bin mir noch nicht so ganz sicher, ob die Implementierung dort
auch funktioniert.


> PS @Robert: wenn Du noch Schreibrechte willst/brauchst, kannste Dich gerne
> off-list melden.
Mache ich. Ich habe meine Erkenntnisse bisher in eine lokale Kopie der
Tabelle eingetragen und kann das an diese zentrale Stelle übertragen.
Die wichtigsten Informationen dürften ermittelt sein - zumindest für
diese Datenversion. Wie Andreas schon schrieb, gibt es bei anderen
Unternehmen auch Dateien mit Datenversion 5, bei denen einige
Informationen nicht vorhanden sind, oder zumindest nicht in der
bekannten Art und Weise. Das kann man auch simulieren, indem man einen
anderen Parameter für h2g-direct verwendet.

>
> PPS: Habe übrigens spaßenshalber mal den Traffic der INSA-iOS-App gesnifft,
> die macht natürlich wieder ganz andere Abfragen, irgendwas
> application/x-b-xml? Aber als in dem nicht gzip, aber vermutlich anders
> komprimierten BLOB nicht ein einziger String zu erkennen war, hab ich's auch
> schnell wieder sein gelassen.
Och nö... :D

Andreas Schildbach

unread,
Jul 31, 2012, 9:36:02 AM7/31/12
to public-transport...@googlegroups.com
Ich habe noch herausgefunden, dass die INSA-App noch nicht genau
identifizierte Start/Ziele auf alle F�lle vor dem h2g-direct-Aufruf
identifiziert und daf�r die selbe XML-API wie die Autovervollst�ndigung
nutzt. Ich habe das jetzt genau so implementiert.

Robert, Dein Einwand bzgl. des Durchreichens der Strings-Tabelle und des
Encodings ist berechtigt - ich habe daf�r jetzt eine Klasse angelegt.
Von dieser gibt es nur eine Instanz, ist also nicht so schlimm.

Die ganzen Integer.reverseBytes(is.readInt()) habe ich jetzt in eine
eigene Subklasse von LittleEndianDataInputStream verschoben, das
vereinfacht den Code auf is.readIntReverse(). Funktionen fuer short analog.

�brigens w�nschen sich viele User, da� man einen vollst�ndigen
Linienverlauf anzeigen kann, also nicht nur der Abschnitt den man im
Rahmen einer Verbindung f�hrt, sondern von Anfang zur Endstation. Glaubt
ihr, man kann dies auch �ber h2g abfragen?

Nochmal Robert, ich glaube die Daten in einem char-Array zu halten ist
keine gute Idee. Klar musst Du Deine Routinen dann an den Umstand
anpassen, dass Bytes in Java vorzeichenbehaftet sind. Aber ich glaube,
daf�r m�sste es schon entsprechende Routinen im JDK geben.


On 07/30/2012 08:28 AM, Robert Vollmer wrote:
>> Was die Reihenfolge der Verbindungen bei einem Tageswechsel angeht, scheint
>> tats�chlich zu gelten:
>> Das Verbindungs-Array ist nur nach Uhrzeit sortiert, also im Fall eines
>> Tageswechsels ist die Reihenfolge "falsch". Einerseits ist evtl. das letzte
>> Feld der Eintr�ge in der "Verkehrstage-Tabelle" geeignet, diesen Fall zu
>> erkennen, zumindest kann damit anscheinend das Datum relativ zum Reisedatum
>> ermittelt werden. Aber unabh�ngig davon sind auch die ConnectionId-Attribute
>> in der Darstellungs-Reihenfolge, C0-0 ist die fr�heste Verbindung, aber eben
>> nicht immer die erste im Array.
>
> Es ist der letzte Eintrag in der "Verkehrstage-Tabelle". Das ist wie
> von dir vermutet eine Bitmaske, wobei die beiden Eintr�ge davor auch
> noch eine Rolle spielen.
> Das habe ich durch Analyse der INSA-App herausgefunden, wobei die
> Funktion dort zur�ckgibt, ob eine Verbindung an einem bestimmten Tag
> Wenn man sich in der Bahn-App einen pers�nlichen Abfahrtsplan
> erstellen l�sst, bekommt man eine Datei im gleichen Format (allerdings
> mit �lterer Header-Version).
> Ich bin mir noch nicht so ganz sicher, ob die Implementierung dort
> auch funktioniert.
>
>
>> PS @Robert: wenn Du noch Schreibrechte willst/brauchst, kannste Dich gerne
>> off-list melden.
> Mache ich. Ich habe meine Erkenntnisse bisher in eine lokale Kopie der
> Tabelle eingetragen und kann das an diese zentrale Stelle �bertragen.
> Die wichtigsten Informationen d�rften ermittelt sein - zumindest f�r
> diese Datenversion. Wie Andreas schon schrieb, gibt es bei anderen
> Unternehmen auch Dateien mit Datenversion 5, bei denen einige
> Informationen nicht vorhanden sind, oder zumindest nicht in der
> bekannten Art und Weise. Das kann man auch simulieren, indem man einen
> anderen Parameter f�r h2g-direct verwendet.
>
>>
>> PPS: Habe �brigens spa�enshalber mal den Traffic der INSA-iOS-App gesnifft,
>> die macht nat�rlich wieder ganz andere Abfragen, irgendwas
>> application/x-b-xml? Aber als in dem nicht gzip, aber vermutlich anders
>> komprimierten BLOB nicht ein einziger String zu erkennen war, hab ich's auch
>> schnell wieder sein gelassen.
> Och n�... :D
>

Robert Vollmer

unread,
Jul 31, 2012, 2:22:06 PM7/31/12
to public-transport...@googlegroups.com
Am 31.07.2012 15:36, schrieb Andreas Schildbach:
> Ich habe noch herausgefunden, dass die INSA-App noch nicht genau
> identifizierte Start/Ziele auf alle F�lle vor dem h2g-direct-Aufruf
> identifiziert und daf�r die selbe XML-API wie die Autovervollst�ndigung
> nutzt. Ich habe das jetzt genau so implementiert.

Genau, hatte ich glaube ich auch schon angedeutet. Ich hatte es allerdings im abstrakten Provider implementiert, bzw. die Unterscheidung zwischen bin�r und XML direkt in queryConnections eingebaut, daher konnte ich die dort schon vorhandene Logik verwenden.

> Robert, Dein Einwand bzgl. des Durchreichens der Strings-Tabelle und des
> Encodings ist berechtigt - ich habe daf�r jetzt eine Klasse angelegt.
> Von dieser gibt es nur eine Instanz, ist also nicht so schlimm.
>
> Die ganzen Integer.reverseBytes(is.readInt()) habe ich jetzt in eine
> eigene Subklasse von LittleEndianDataInputStream verschoben, das
> vereinfacht den Code auf is.readIntReverse(). Funktionen fuer short analog.

Das klingt schon ganz gut. :) Es gibt sicherlich noch so einige Sachen, die ich anders machen w�rde (bzw. gemacht habe), aber das ist sicherlich auch Ansichtssache... letztendlich musst es f�r dich als Projekteigner passen, du wirst schlie�lich viel mehr Zeit mit dem Code verbringen. Daher spare ich mir die Zeit, wenn es nicht gerade um echte Bugs geht.


> �brigens w�nschen sich viele User, da� man einen vollst�ndigen
> Linienverlauf anzeigen kann, also nicht nur der Abschnitt den man im
> Rahmen einer Verbindung f�hrt, sondern von Anfang zur Endstation. Glaubt
> ihr, man kann dies auch �ber h2g abfragen?

Ich habe einfach mal die INSA-App befragt und den Traffic analysiert.

Originalanfrage: http://reiseauskunft.insa.de/bin/stboard.exe/dn?productsFilter=11111111111111&boardType=dep&clientSystem=Android15&sTI=1&hcount=0&L=vs_java3&date=26.07.2012&REQTrain_name=RE%20%203780&androidversion=1.0.2&time=05%3a54&input=%238010085&start=yes&clientDevice=GT-I9100&htype=GT-I9100&dirInput=8010184&clientType=ANDROID

Ohne die ganz offensichtlich nicht notwendigen Parameter:
http://reiseauskunft.insa.de/bin/stboard.exe/dn?productsFilter=11111111111111&boardType=dep&sTI=1&hcount=0&L=vs_java3&date=26.07.2012&REQTrain_name=RE%20%203780&time=05%3a54&input=%238010085&start=yes&dirInput=8010184

productsFilter: ist bekannt
sTI und hcount: keine Ahnung
L=vs_java3: ganz wichtig, damit XML rauskommt
date, time und boardType=dep: notwendig, gibt die Suchkriterien f�r die Verbindung an. Sollte also die geplante Abfahrtszeit sein.
REQTrain_name: sollte - falls vorhanden - angegeben werden, um das richtige Resultat zu bekommen
input: Startpunkt der Suche. Kann ruhig eine Zwischenstation sein, wenn time dazu passt. %23 = #, geht aber auch ohne
start=yes: ben�tigt
dirInput: Richtung der Verbindung. Sollte also das bekannte Ziel der (Teil-)Verbindung sein

Den Code zum Parsen k�nnte �hnlich sein wie in xmlNearbyStations().

Ich pers�nlich f�nde so eine Funktion auch ganz nett.
Wichtiger f�nde ich allerdings, die Versp�tungen zu sehen. Die Daten liegen ja bereit, sowohl f�r die Verbindungen als auch f�r die Zwischenstopps. Ich hatte daher - falls vorhanden - die Realdaten verwendet. Da fehlte nur noch etwas Transparenz, dass eine Versp�tung vorliegt und wie gro� diese ist.
Au�erdem finde ich, dass bei Zwischenstopps die Ankunftszeit wichtiger ist als die Abfahrtszeit. Dann hat man n�mlich noch die Chance ggf. fr�her in eine andere Bahn umzusteigen. Man kann ja draufdr�cken und sieht dann die Abfahrten an dieser Station - und f�r die ist es uninteressant, ob mein vorheriger Zug noch eine Viertelstunde steht.

> Nochmal Robert, ich glaube die Daten in einem char-Array zu halten ist
> keine gute Idee. Klar musst Du Deine Routinen dann an den Umstand
> anpassen, dass Bytes in Java vorzeichenbehaftet sind. Aber ich glaube,
> daf�r m�sste es schon entsprechende Routinen im JDK geben.

Das stimmt schon. Wie gesagt, der Hauptgrund war, dass es eine passende Methode schon gab. Zum Umwandeln braucht man nicht mal eine Funktion, ein einfaches (x & 0xff) reicht. Das hatte ich ja vorher auch schon so.

Robert

unread,
Aug 1, 2012, 3:56:54 AM8/1/12
to public-transport...@googlegroups.com
Heute morgen habe ich Version 7.28 installiert und zum Testen meine Variante deaktiviert. Leider habe ich schon einige Bugs gefunden:

1. Crash beim Abrufen weiterer Verbindungen ("error 1 on http://...). Ich habe einen Android-Bugreport abgeschickt, ich hoffe der kommt mitsamt Stacktrace an. Mittlerweile konnte ich herausfinden, dass der Crash dann auftritt, wenn eine Minute seit der initialen Anfrage vergangen ist. Leider passen die Zeilenangaben nicht zu diesem Repository (scheint also nicht synchronisiert zu sein), daher konnte ich noch nicht nachvollziehen, wo genau der Fehler liegt. Meine Vermutung wäre, dass der "ld"-Parameter doch relevant ist. Siehe mein Coding, da wird der ermittelt und verwendet.

2. Teilweise fehlen Zeiten für die Zwischenhalte. Ein Beispiel:
https://www.dropbox.com/s/ayv41d7fl4t1zad/Screenshot_2012-08-01-07-31-36.png
https://www.dropbox.com/s/udfuau0ynna7cj7/Screenshot_2012-08-01-07-31-54.png
Das würde automatisch behoben werden, wenn die Ankunftszeiten für Zwischenstops verwendet würden (s.o.). Zudem fehlen die Haltestellen für die Zwischenhalte (werden laut der Version im Repo gar nicht ermittelt). Auch hier kannst du in meinem Code sehen, wie die Angaben ermittelt werden können.

3. Manchmal sind die Verbindungen nicht richtig geordnet: https://www.dropbox.com/s/fg0s32xm66at99w/Screenshot_2012-08-01-07-34-24.png
Das wird daran liegen, dass die Verbindungen nur nach Zeit, aber nicht nach Datum geordnet von der Schnittstelle geliefert werden. Ich sehe es allerdings eher als die Aufgabe von Öffi an, die neuen Verbindungen richtig einzuordnen. Es ist ja auch nicht auszuschließen, dass eine frühere Verbindung so viel Verspätung hat, dass sie nach einer schon ermittelten Verbindung startet. Momentan kann das leider noch nicht auftreten, aber ich hoffe ja, dass in Zukunft die realen Zeiten und Gleise (falls vorhanden) angezeigt werden.

Andreas Schildbach

unread,
Aug 1, 2012, 4:36:10 AM8/1/12
to public-transport...@googlegroups.com
On 08/01/2012 09:56 AM, Robert wrote:

> 1. Crash beim Abrufen weiterer Verbindungen ("error 1 on http://...).

Es gibt schon eine Version 7.29, in der der Error-Code zu einer "session
expired" Meldung fuehrt.

> Meine Vermutung
> wäre, dass der "ld"-Parameter doch relevant ist. Siehe mein Coding, da
> wird der ermittelt und verwendet.

Ich habe ihn bisher zwar ermittelt, aber nicht verwendet, weil ich sehen
wollte ob er wirklich noetig ist.

> 2. Teilweise fehlen Zeiten für die Zwischenhalte.
> Das würde automatisch behoben werden, wenn die Ankunftszeiten für
> Zwischenstops verwendet würden (s.o.). Zudem fehlen die Haltestellen für
> die Zwischenhalte

Du nutzt jetzt "Deutschland", nehme ich an?

Was meinst Du mit "Haltestellen"? Gleis/Platformangabe?

> 3. Manchmal sind die Verbindungen nicht richtig geordnet

Tja, nach was wuerdest Du denn sortieren? Ich denke die Koenigsloesung
waere Abfahrtszeit, wenn der User "ab" gewaehlt hat und Ankunftszeit,
wenn er "an" gewaehlt hat. Ich behalte das im Kopf.

Cheers,

Andreas

Robert Vollmer

unread,
Aug 1, 2012, 4:59:07 AM8/1/12
to public-transport...@googlegroups.com
>> 1. Crash beim Abrufen weiterer Verbindungen ("error 1 on http://...).
>
> Es gibt schon eine Version 7.29, in der der Error-Code zu einer "session
> expired" Meldung fuehrt.

Ok, die ist aber noch nicht im Store, zumindest bekomme ich sie auch
nach dem Leeren vom Cache nicht.
Kannst du dann den aktuellen Stand der Provider wieder ins Repo pushen?

>
>> Meine Vermutung
>> wäre, dass der "ld"-Parameter doch relevant ist. Siehe mein Coding, da
>> wird der ermittelt und verwendet.
>
> Ich habe ihn bisher zwar ermittelt, aber nicht verwendet, weil ich sehen
> wollte ob er wirklich noetig ist.

Naja, also länger als eine Minute sollte die Session schon verwendbar
sein, also gehe ich davon aus, dass etwas mit der Anfrage nicht
stimmt. Das Problem ist ja gut reproduzierbar, daher lässt sich leicht
testen, ob der Parameter etwas bringt.

>
>> 2. Teilweise fehlen Zeiten für die Zwischenhalte.
>> Das würde automatisch behoben werden, wenn die Ankunftszeiten für
>> Zwischenstops verwendet würden (s.o.). Zudem fehlen die Haltestellen für
>> die Zwischenhalte
>
> Du nutzt jetzt "Deutschland", nehme ich an?

Ja, genau. Leipzig nutzt mir nicht viel. ;)

> Was meinst Du mit "Haltestellen"? Gleis/Platformangabe?
Sorry, genau das meinte ich. Die sind ganz einfach als Strings ohne
den Prefix "Gleis " abgespeichert. Ich bin leider noch nicht dazu
gekommen, die Tabelle zu aktualisieren, aber im Code steht ja
bekanntlich die Wahrheit. ;)

>
>> 3. Manchmal sind die Verbindungen nicht richtig geordnet
>
> Tja, nach was wuerdest Du denn sortieren? Ich denke die Koenigsloesung
> waere Abfahrtszeit, wenn der User "ab" gewaehlt hat und Ankunftszeit,
> wenn er "an" gewaehlt hat. Ich behalte das im Kopf.

Gute Frage... so wie im Screenshot sieht es halt durcheinander aus.
Für "ab" wäre die Abfahrtzeit natürlich passend. Bei "an" bin ich mir
nicht so sicher. Die weitere Frage ist ja: Was will man mit einer
solchen Abfrage sehen? Wohl möglichst Verbindungen, die zum einen
rechtzeitig ankommen, aber auch möglichst kurz sind oder wenige
Umstiege haben. Da wäre vielleicht zunächst mal eine zusätzliche Linie
mit der gewählten Ankunftszeit hilfreich, um schneller sehen zu
können, welche Verbindung noch rechtzeitig ankommt und welche nicht.
Sortierung nach Ankunftszeit würde bedeuten, dass die Unterkanten
auf/absteigend zu sehen sind. So kann man zunächst danach aussuchen,
welche Bahn möglichst pünktlich ankommt. Anschließend vergleicht man
die Länge der Balken bzw. deren Oberkante und findet so die
schnellste/einfachste Verbindung, und zwar nach links. Klingt gut. Bei
Sortierung nach Abfahrtszeit könnte man ab der aktuellen Zeit von
links nach rechts suchen und die späteste Verbindung nehmen, die noch
rechtzeitig ankommt. Geht auch, aber Sortierung nach Ankunftszeit in
Verbindung mit einer zusätzlichen Markierungslinie wäre besser.

Robert Vollmer

unread,
Aug 2, 2012, 3:28:28 AM8/2/12
to public-transport...@googlegroups.com
So, ich habe eben endlich mal meine Ergänzungen in die Tabelle
eingetragen. Gestern habe ich noch angefangen, einen weiteren Block zu
untersuchen, das dürfte der "Unbekannte Block 2" sein. Der ist im
Zusammenhang mit ausfallenden Verbindungen (Tipp: Ruhland ->
Hoyerswerda) aufgefallen. Ganz in der Nähe davon gibt es auch noch
Attribute, die mehr Informationen darüber geben (z.B. Grund der
Störung). Die Startindizes für für die Attributetabelle habe ich schon
gefunden, die sind auch in Abständen von 20 Byte, aber ich weiß noch
nicht, wie man hinkommt. Ich werde wohl mal die Originalapp laufen
lassen und über mein Framework mitloggen, auf welche Adressen
zugegriffen wird. Vielleicht erkenne ich darüber ein Muster (bzw. kann
dann auch einen Stacktrace von diesen Zugriffen ziehen).

Übrigens habe ich gesehen, dass in Version 7.30 der Crash nach einer
Minute nicht mehr Auftritt, die Zeiten jetzt die Abfahrtszeiten sind
und bei den Zwischenhalten auch die Gleise angezeigt werden. Toll! :)
Außerdem ist mir aufgefallen, dass die Zeiten einiger Zwischenhalte
kursiv dargestellt sind. Möglicherweise war das schon länger so, aber
mir ist es gestern erst aufgefallen. Was ist denn die Bedeutung davon?
Hat das was mit Echtzeit-Daten zu tun, die in der aktuellen
pte-Version im Repo jetzt verwendet werden?

Andreas Schildbach

unread,
Aug 2, 2012, 5:45:55 AM8/2/12
to public-transport...@googlegroups.com
On 08/02/2012 09:28 AM, Robert Vollmer wrote:

> So, ich habe eben endlich mal meine Erg锟絥zungen in die Tabelle
> eingetragen.

Vielen Dank! Ein paar Anmerkungen:

Felder 0x4 und 0x12 im globalen Header sind dann wohl vom Typ String?
Leider ist dieses Feld in der normalen Verbindungsauskunft nicht belegt,
denn sonst k锟絤e ich 锟絙er den "L"-Parameter an die IDs von Haltestellen
oder POIs.

Zwischenstopp-Tabelle Felder 4 und 6 beschreiben vermutlich die
planm锟斤拷igen Gleise, nicht die erwarteten.

> 锟絙rigens habe ich gesehen, dass in Version 7.30 der Crash nach einer
> Minute nicht mehr Auftritt, die Zeiten jetzt die Abfahrtszeiten sind
> und bei den Zwischenhalten auch die Gleise angezeigt werden. Toll! :)

Ja, ich habe gestern viel an 锟絝fi gearbeitet und die Datenstrukturen so
erweitert, dass es zu "Positionen" (Gleis/Bahnsteig etc.) neben den
Plandaten auch die vorhergesagten Daten gibt. Ausserdem enthaelt ein
Zwischenstopp nun sowohl Ankunft als auch Abfahrt und der Client kann
wenn er will auch beides anzeigen.

> Au锟絜rdem ist mir aufgefallen, dass die Zeiten einiger Zwischenhalte
> kursiv dargestellt sind. M锟絞licherweise war das schon l锟絥ger so, aber
> mir ist es gestern erst aufgefallen. Was ist denn die Bedeutung davon?
> Hat das was mit Echtzeit-Daten zu tun, die in der aktuellen
> pte-Version im Repo jetzt verwendet werden?

Kursiv bedeutet generell "vorhergesagt". Nicht kursiv sind entweder
Plandaten oder die Herkunft ist nicht klar. Diese Visualisierung gibts
schon seit den ersten Tagen von 锟絝fi, aber ich habe das nie richtig
dokumentiert )-:

Ich wuerde gerne nochmal auf die ConnectionId zurueckkommen:

Die BVG unter http://mobil.bvg.de/Fahrinfo/bin/query.bin/dox liefert
keine ConnectionId in den Attributen aus, wohl aber kennt die Webseite
(ohne h2g-direct) diese. Das sieht man, wenn man mit der Maus ueber die
einzelnen Verbindungen der Verbindungsuebersicht faehrt, da sieht man
die ID im URL-Parameter "co".

Eine ID hat uebrigens immer die Form "C<int>-<int>". Ich erwarte also
ggf. zwei shorts oder ints in den Binaerdaten. Ich hab schon ueberall
gesucht, wo Verbindungs-spezifische Daten sein koennen:

Die 12 Bytes in der Verbindungs-锟絙ersicht, Gesamtverbindungen sind schon
vollstaendig entschluesselt.

Und die 12 Bytes in der "Strecken-Info je Verbindung" sind auch entweder
bekannt (erste 4 bytes) oder enthalten konsequent immer das gleiche
0xffff ffff 0000 000 (letzte 8 bytes).

An welchen Orten koennte sowas noch stecken?

Robert Vollmer

unread,
Aug 2, 2012, 6:26:37 AM8/2/12
to public-transport...@googlegroups.com
> Felder 0x4 und 0x12 im globalen Header sind dann wohl vom Typ String?
> Leider ist dieses Feld in der normalen Verbindungsauskunft nicht belegt,
> denn sonst käme ich über den "L"-Parameter an die IDs von Haltestellen
> oder POIs.

Stimmt, das hatte ich wohl übersehen beim Eintragen. Ich habe auch
lange versucht herauszufinden, wann dort ein Wert steht, und bin
schließlich auf die persönlichen Fahrpläne gekommen. Im Originalcode
gibt es in der Tat auch eine Funktion, die aus dem @L die ID
extrahiert. Aber wie du schon sagst - das Feld ist leider bei normalen
Abfragen leer.

> Zwischenstopp-Tabelle Felder 4 und 6 beschreiben vermutlich die
> planmäßigen Gleise, nicht die erwarteten.

Ja. Ich meine, das hätte ich auch so eingetragen. In 0x10 und 0x12
stehen ja die erwarteten Gleise. Wobei, zwischenzeitlich hatte ich
mich in den Zeilen etwas vertan, das hatte ich aber noch korrigiert.

>
>> Außerdem ist mir aufgefallen, dass die Zeiten einiger Zwischenhalte
>> kursiv dargestellt sind. Möglicherweise war das schon länger so, aber
>> mir ist es gestern erst aufgefallen. Was ist denn die Bedeutung davon?
>> Hat das was mit Echtzeit-Daten zu tun, die in der aktuellen
>> pte-Version im Repo jetzt verwendet werden?
>
> Kursiv bedeutet generell "vorhergesagt". Nicht kursiv sind entweder
> Plandaten oder die Herkunft ist nicht klar. Diese Visualisierung gibts
> schon seit den ersten Tagen von Öffi, aber ich habe das nie richtig
> dokumentiert )-:

Ah, d.h. es wird jetzt die Abfahrtszeit angezeigt und wenn vorhanden
sogar die vorausgesagte Zeit (dann kursiv dargestellt)? Wunderbar. :)
Leider funktioniert das wohl noch nicht für die Start- und
Stophaltestelle. Ich habe gerade eben eine Verbindung von Mannheim
nach Frankfurt gefunden (Start 12:17), bei der es 25 Minuten
Verspätung gibt. Ich würde erwarten, dass dann 12:42 als Abfahrt
kursiv angezeigt wird in den Details und möglichst auch in der
Verbindungsübersicht (sonst muss ich ja in alle reingucken).

> Ich wuerde gerne nochmal auf die ConnectionId zurueckkommen:
>
> Die BVG unter http://mobil.bvg.de/Fahrinfo/bin/query.bin/dox liefert
> keine ConnectionId in den Attributen aus, wohl aber kennt die Webseite
> (ohne h2g-direct) diese. Das sieht man, wenn man mit der Maus ueber die
> einzelnen Verbindungen der Verbindungsuebersicht faehrt, da sieht man
> die ID im URL-Parameter "co".
>
> Eine ID hat uebrigens immer die Form "C<int>-<int>". Ich erwarte also
> ggf. zwei shorts oder ints in den Binaerdaten. Ich hab schon ueberall
> gesucht, wo Verbindungs-spezifische Daten sein koennen:
>
> Die 12 Bytes in der Verbindungs-Übersicht, Gesamtverbindungen sind schon
> vollstaendig entschluesselt.
>
> Und die 12 Bytes in der "Strecken-Info je Verbindung" sind auch entweder
> bekannt (erste 4 bytes) oder enthalten konsequent immer das gleiche
> 0xffff ffff 0000 000 (letzte 8 bytes).
>
> An welchen Orten koennte sowas noch stecken?

Ich schau bei Gelegenheit nochmal nach. Ich hatte glaube ich noch
irgendwo zwei Dateien, wo ich an der Sequence-ID gedreht hatte bei der
Abfrage und die inhaltlich gleich waren, nur mit anderen
Connection-IDs. Ansonsten kann ich auch mal schauen, ob ich im Code
etwas finde, aber ich weiß nicht so recht, wofür genau die die ID
verwenden.

Andreas Schildbach

unread,
Aug 5, 2012, 1:52:21 PM8/5/12
to public-transport...@googlegroups.com
Ich hab mir mal die Daten vom SBB (Schweiz) angesehen.

Etwas merkwuerdig ist schonmal die Tatsaeche, dass die Antwort auf die
Abfrage mit h2g-direct=11 scheinbar doppelt GZIP-verpackt ist. Ich muss
jedenfalls zwei GZIPInputStreams ineinander schachteln.

In der XML-Variante kann man mit "deliverPolyline=1" im ConReq eine
Polygonlinie anfordern. Man sieht den genauen Linienverlauf auch in den
Karten, die man auf der Webseite anzeigen kann. Das scheint in der
Bin�rversion zu fehlen.

�brigens auch interessant: Es gibt eigentlich sowohl bei der DB aus auch
der SBB eine Belegungsangabe (Capacity1st, Capacity2nd). Steckt das
evtl. in den Tafifdaten drin?

Robert Vollmer

unread,
Aug 5, 2012, 7:17:53 PM8/5/12
to public-transport...@googlegroups.com
> Etwas merkwuerdig ist schonmal die Tatsaeche, dass die Antwort auf die
> Abfrage mit h2g-direct=11 scheinbar doppelt GZIP-verpackt ist. Ich muss
> jedenfalls zwei GZIPInputStreams ineinander schachteln.

Ich habe zum Analysieren meist die Datei heruntergeladen, entpackt und analysieren lassen. Das verhindert, dass einem die Daten unter dem Hintern wegge�ndert werden und man hat die M�glichkeit, sich das mal im Hexeditor anzusehen. Ich musste meine SBB-Testdatei nur einmal entpacken.

Au�erdem konnte ich mit diese heruntergeladenen Dateien in die Bahnapp einschleusen und mir so die Originalausgabe genauer angucken, genau mitloggen lassen, auf welche Bytes zugegriffen wird und auch mit leicht ge�nderten Dateien experimentieren.

> In der XML-Variante kann man mit "deliverPolyline=1" im ConReq eine
> Polygonlinie anfordern. Man sieht den genauen Linienverlauf auch in den
> Karten, die man auf der Webseite anzeigen kann. Das scheint in der
> Bin�rversion zu fehlen.
>
> �brigens auch interessant: Es gibt eigentlich sowohl bei der DB aus auch
> der SBB eine Belegungsangabe (Capacity1st, Capacity2nd). Steckt das
> evtl. in den Tafifdaten drin?
>

Es gibt jetzt eigentlich nur noch einen unbekannten, bislang immer leeren Block. Der Rest sind einige Fragezeichen. Ich sch�tze mal, dass es diese Info einfach nicht in den Bin�rdaten gibt. In den Tarifinformationen k�nnen sie bei DB und SBB zumindest nicht stecken, denn die gibt es dort gar nicht. Wenn es eine App gibt, die irgendwelche noch unbekannten Informationen anzeigt, kann ich sie mir gerne ansehen, aber die von der SBB verwendet selbst XML und ist ganz anders aufgebaut. Und die CVV-App macht neue Anfrage an die stboard.exe, um sich den Linienverlauf zu holen - dort stecken sowohl Koordinaten als auch "capacity="0|0"" drin. Au�erdem ruft sie noch ein JSON ab, in dem es auch das Stichwort "pathIdx" gibt. Welche Daten genau zur�ckkommen habe ich mir nicht angesehen.

�brigens hattest du doch in die Tabelle eingetragen, dass bei http://hafas.websrv05.reiseinfo.no/bin/dev/nri/ das erste Feld bei der Strecken-Info den Wert 0x0006 hat. Kannst du das bitte nochmal �berpr�fen? Bei meinen Versuchen war der Pointer zur Strecken-Info = 0, sprich es gibt diesen Block gar nicht. Wenn diese Pr�fung bei dir fehlte, w�rdest du auf das allererste Word der Datei zugreifen, das bei mir 6 war.


Ich habe die Tabelle noch um die Informationen �ber St�rungen und ein paar andere Sachen erg�nzt. Einfach mal den �nderungslog anschauen (auch wenn Google merkw�rdig gruppiert hat). Vielleicht kann ja noch das ein oder andere noch in �ffi Einzug erhalten, damit man sich nicht zwei Apps installiert halten muss (so selten sind ja die St�rungen leider nicht). Ganz besonders wichtig f�nde ich das Flag "Verbindung f�llt aus" (Zusatz-Informationen == 0x0002). Ich habe verifiziert, dass dieses Byte f�r die entsprechende Anzeige in der DB-App zust�ndig ist. In den Details w�ren sicherlich auch die Infos zu den Gr�nden - sofern vorhanden - ganz nett.

Au�erdem habe ich noch die Abdeckung analysiert. Ich habe alle Bytes in zwei Dateien den Bl�cken aus der Tabelle zuordnen k�nnen. Klar fehlen vereinzelt noch Bedeutungen einzelner Bytes, aber es gibt zumindest keine "lose herumschwebende" Bytes mehr. Das verst�rkt meine Vermutung, dass es bei der BVG gar keine ConnectionId gibt. Da musst du dir wohl eine andere Art �berlegen, Duplikate zu finden. Wie gesagt, mit einem Hash aus ein paar statischen, aber eindeutigen Daten zu einer Verbindung sollte das recht einfach gehen.

Damit neigt sich f�r das Bin�rformat wohl auch der Analysebedarf dem Ende zu. Bei den restlichen Daten w�rde ich eher von den Originalapps ausgehen und schauen, welche Daten die noch zus�tzlich anzeigen k�nnen, die man dann in der Datei suchen kann.

Andreas Schildbach

unread,
Aug 6, 2012, 6:52:21 AM8/6/12
to public-transport...@googlegroups.com
On 08/06/2012 01:17 AM, Robert Vollmer wrote:

>> Etwas merkwuerdig ist schonmal die Tatsaeche, dass die Antwort auf die
>> Abfrage mit h2g-direct=11 scheinbar doppelt GZIP-verpackt ist. Ich muss
>> jedenfalls zwei GZIPInputStreams ineinander schachteln.
>
> Ich habe zum Analysieren meist die Datei heruntergeladen, entpackt und
> analysieren lassen. Das verhindert, dass einem die Daten unter dem
> Hintern wegge�ndert werden und man hat die M�glichkeit, sich das mal im
> Hexeditor anzusehen. Ich musste meine SBB-Testdatei nur einmal entpacken.

Mit "gunzip" musste ich auch nur einmal entpacken. Evtl. enthaelt das
Tool schon eine Logik fuer solche Faelle?

Ich hab jetzt in den ParserUtils ab Zeile 273 eine Logik, die auch den
GZIP Header prueft.

> Wenn es eine App gibt, die irgendwelche
> noch unbekannten Informationen anzeigt, kann ich sie mir gerne ansehen,

Danke, ich werde die Augen offen halten.

> Und die CVV-App macht neue Anfrage an die stboard.exe, um sich den
> Linienverlauf zu holen

Wer/was/wo ist denn CVV? Ist das ne Android-App?

> �brigens hattest du doch in die Tabelle eingetragen, dass bei
> http://hafas.websrv05.reiseinfo.no/bin/dev/nri/ das erste Feld bei der
> Strecken-Info den Wert 0x0006 hat. Kannst du das bitte nochmal
> �berpr�fen? Bei meinen Versuchen war der Pointer zur Strecken-Info = 0,
> sprich es gibt diesen Block gar nicht. Wenn diese Pr�fung bei dir
> fehlte, w�rdest du auf das allererste Word der Datei zugreifen, das bei
> mir 6 war.

Du hast Recht, ich hatte den Zeiger auf die Strecken-Info nicht
geprueft. Ich habe den entsprechenden Kommentar wieder entfernt.

> Ich habe die Tabelle noch um die Informationen �ber St�rungen und ein
> paar andere Sachen erg�nzt. Einfach mal den �nderungslog anschauen (auch
> wenn Google merkw�rdig gruppiert hat). Vielleicht kann ja noch das ein
> oder andere noch in �ffi Einzug erhalten, damit man sich nicht zwei Apps
> installiert halten muss (so selten sind ja die St�rungen leider nicht).

Puh, gar nicht so einfach da ein gemeinsames Datenmodell (mit EFA) zu
finden.

> Ganz besonders wichtig f�nde ich das Flag "Verbindung f�llt aus"
> (Zusatz-Informationen == 0x0002).

Als schnelle Loesung wird eine so gekennzeichnete Verbindung schlicht
nicht mehr angezeigt.

> Au�erdem habe ich noch die Abdeckung analysiert. Ich habe alle Bytes in
> zwei Dateien den Bl�cken aus der Tabelle zuordnen k�nnen. Klar fehlen
> vereinzelt noch Bedeutungen einzelner Bytes, aber es gibt zumindest
> keine "lose herumschwebende" Bytes mehr. Das verst�rkt meine Vermutung,
> dass es bei der BVG gar keine ConnectionId gibt. Da musst du dir wohl
> eine andere Art �berlegen, Duplikate zu finden. Wie gesagt, mit einem
> Hash aus ein paar statischen, aber eindeutigen Daten zu einer Verbindung
> sollte das recht einfach gehen.

Ok, dann werde ich wohl die Planzeiten +
Haltestellen-IDs/Geo-Koordinaten nehmen.

> Damit neigt sich f�r das Bin�rformat wohl auch der Analysebedarf dem
> Ende zu. Bei den restlichen Daten w�rde ich eher von den Originalapps
> ausgehen und schauen, welche Daten die noch zus�tzlich anzeigen k�nnen,
> die man dann in der Datei suchen kann.

Nochmal vielen Dank fuer Deine Hilfe! So weit w�re ich nie gekommen.

Cheers,

Andreas

Robert Vollmer

unread,
Aug 6, 2012, 7:37:23 AM8/6/12
to public-transport...@googlegroups.com
>> Und die CVV-App macht neue Anfrage an die stboard.exe, um sich den
>> Linienverlauf zu holen
>
> Wer/was/wo ist denn CVV? Ist das ne Android-App?

Das ist die VBB-App, nur etwas nach links verrutscht. ;)

>> Ich habe die Tabelle noch um die Informationen über Störungen und ein
>> paar andere Sachen ergänzt. Einfach mal den Änderungslog anschauen (auch
>> wenn Google merkwürdig gruppiert hat). Vielleicht kann ja noch das ein
>> oder andere noch in Öffi Einzug erhalten, damit man sich nicht zwei Apps
>> installiert halten muss (so selten sind ja die Störungen leider nicht).
>
> Puh, gar nicht so einfach da ein gemeinsames Datenmodell (mit EFA) zu
> finden.
>
>> Ganz besonders wichtig fände ich das Flag "Verbindung fällt aus"
>> (Zusatz-Informationen == 0x0002).
>
> Als schnelle Loesung wird eine so gekennzeichnete Verbindung schlicht
> nicht mehr angezeigt.

Das hilft schonmal. In Zukunft kann das ja noch etwas expliziter auf
den Ausfall und andere Störungen hingewiesen werden. Es ist nicht
dringend, aber da sehe ich noch Potenzial, die App weiter zu
verbessern.

> Nochmal vielen Dank fuer Deine Hilfe! So weit wäre ich nie gekommen.

Gerne. Sag Bescheid, wenn noch irgendwas zu analysieren ist. Und danke
für Öffi! ;)

Andreas Schildbach

unread,
Aug 8, 2012, 6:20:31 AM8/8/12
to public-transport...@googlegroups.com
On 08/06/2012 01:37 PM, Robert Vollmer wrote:

>>> Und die CVV-App macht neue Anfrage an die stboard.exe, um sich den
>>> Linienverlauf zu holen
>>
>> Wer/was/wo ist denn CVV? Ist das ne Android-App?
>
> Das ist die VBB-App, nur etwas nach links verrutscht. ;)

Oh, hab mir die VBB-App daraufhin nochmal angesehen. Interessanterweise
ermittelt die auch keinen genaueren Linienverlauf, als sie schon aus der
Verbindung auslesen kann. Sprich: Luftlinie zwischen den Haltestellen.

Naja, vielleicht muss man Hafas einfach mal wieder etwas Zeit geben,
hinterherzuentwickeln. Dann haben sie vielleicht wieder Luft, um
genauere Daten zu liefern... (-:

Cheers,

Andreas

Andreas (Öffi)

unread,
Oct 28, 2013, 4:48:44 AM10/28/13
to public-transport...@googlegroups.com
Der Code für die "Binär-API" ist jetzt schon lange im Einsatz und hat sich größtenteils sehr bewährt.

Es gibt jedoch ein Problem, und zwar immer am Tag der Zeitumstellung sind alle Zeiten um eine Stunde verschoben. Merkwürdig ist, daß das Problem nicht die gesamte Winterzeit (oder Sommerzeit) betrifft, sondern wirklich nur eine kurze Zeitspanne bei der Umstellung.

An diejenigen von euch die sich mit der Analyse der bestehenden Apps befasst haben: Ist euch dort eine Logik der Anpassung der Stunden aufgefallen? Evtl. gibt es ja noch ein Bit im Protokoll, das wir übersehen haben?

Robert Vollmer

unread,
Oct 29, 2013, 3:58:08 AM10/29/13
to public-transport...@googlegroups.com
Ich kann es reproduzieren und die normale Bahn-App zeigt die Zeiten richtig an. Das sollte sich also debuggen lassen.
Ich werde mir das mal ansehen, habe allerdings momentan nicht viel Zeit. Falls du selbst etwas herausfindest, lass es mich bitte wissen, damit wir nicht doppelt arbeiten.

Andreas Schildbach

unread,
Oct 29, 2013, 4:10:42 AM10/29/13
to public-transport...@googlegroups.com
Du kannst es im Moment reproduzieren? Das ist merkwuerdig, weil das
Problem normalerweise nur am Tag der Zeitumstellung auftaucht. Die
meisten Reporter haben mir gestern wieder eine Entwarnung geschickt.

Ich bin eigentlich davon ausgegangen, dass wir daher in eine der Apps
reinschauen muessen. Aber die Daten zu vergleichen ist natuerlich auch
ein Weg. An welcher Stelle siehst du das Problem im Moment noch?
> --
> You received this message because you are subscribed to the Google
> Groups "public-transport-enabler-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to public-transport-enabl...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Robert Vollmer

unread,
Oct 29, 2013, 4:26:26 AM10/29/13
to public-transport...@googlegroups.com
Für heute (und gestern und Samstag) ist alles ok. ;) Aber such doch einfach mal mit folgenden Kriterien:
Netz Deutschland, Berlin Hbf => Hamburg Hbf, So 27.10., 6:00 Uhr

In Öffi sind die ersten Verbindungen um 6:12, 7:16, 7:20.
In der DB-App: 7:12, 8:16, 8:20

Du kannst gerne schonmal in die Daten selbst reinschauen, vielleicht findest du ja noch ein entsprechendes Bit. Die Daten selbst werden vermutlich gleich sein, egal welche App sie abruft.
Falls es doch notwendig sein sollte, die DB-App anzugucken (um Klarheit zu schaffen), kann ich das übernehmen, hab einige Erfahrung damit und außerdem ein Framework entwickelt, mit dem ich zur Laufzeit zusätzliches Coding einschleusen kann. ;)

Robert Vollmer

unread,
Oct 29, 2013, 5:33:20 PM10/29/13
to public-transport...@googlegroups.com
Das Problem scheint nicht bei den Daten zu liegen. Die erste Verbindung ist als C8 02 = 712 gespeichert.
Aber das hier d锟絩fte die Ursache sein (in AbstractHafasProvider.time()):

final int hours = value / 100;
final int minutes = value % 100;

final Calendar time = new GregorianCalendar(timeZone());
time.setTimeInMillis(baseDate);
time.add(Calendar.HOUR, hours);
time.add(Calendar.MINUTE, minutes);
time.add(Calendar.DAY_OF_YEAR, dayOffset);

Von Mitternacht bis um 7:12 Uhr sind es aber am 27.10. nicht wie 锟絙lich 7 Stunden und 12 Minuten, sondern aufgrund der Zeitumstellung eine Stunde mehr. Deshalb die Stunde zu fr锟絟, bzw. die Stunde mehr im Fr锟絟jahr. Sollte sehr einfach zu beheben sein:
time.set(Calendar.HOUR, hours);
time.set(Calendar.MINUTE, minutes);


Am 29.10.2013 09:26, schrieb Robert Vollmer:
> F锟絩 heute (und gestern und Samstag) ist alles ok. ;) Aber such doch einfach mal mit folgenden Kriterien:
> Netz Deutschland, Berlin Hbf => Hamburg Hbf, So 27.10., 6:00 Uhr
>
> In 锟絝fi sind die ersten Verbindungen um 6:12, 7:16, 7:20.
> In der DB-App: 7:12, 8:16, 8:20
>
> Du kannst gerne schonmal in die Daten selbst reinschauen, vielleicht findest du ja noch ein entsprechendes Bit. Die Daten selbst werden vermutlich gleich sein, egal welche App sie abruft.
> Falls es doch notwendig sein sollte, die DB-App anzugucken (um Klarheit zu schaffen), kann ich das 锟絙ernehmen, hab einige Erfahrung damit und au锟絜rdem ein Framework entwickelt, mit dem ich zur Laufzeit zus锟絫zliches Coding einschleusen kann. ;)
>
>
> Am 29. Oktober 2013 09:10 schrieb Andreas Schildbach <and...@schildbach.de <mailto:and...@schildbach.de>>:
>
> Du kannst es im Moment reproduzieren? Das ist merkwuerdig, weil das
> Problem normalerweise nur am Tag der Zeitumstellung auftaucht. Die
> meisten Reporter haben mir gestern wieder eine Entwarnung geschickt.
>
> Ich bin eigentlich davon ausgegangen, dass wir daher in eine der Apps
> reinschauen muessen. Aber die Daten zu vergleichen ist natuerlich auch
> ein Weg. An welcher Stelle siehst du das Problem im Moment noch?
>
>
> On 10/29/2013 08:58 AM, Robert Vollmer wrote:
> > Ich kann es reproduzieren und die normale Bahn-App zeigt die Zeiten
> > richtig an. Das sollte sich also debuggen lassen.
> > Ich werde mir das mal ansehen, habe allerdings momentan nicht viel Zeit.
> > Falls du selbst etwas herausfindest, lass es mich bitte wissen, damit
> > wir nicht doppelt arbeiten.
> >
> > --
> > You received this message because you are subscribed to the Google
> > Groups "public-transport-enabler-discuss" group.
> > To unsubscribe from this group and stop receiving emails from it, send
> > an email topublic-transport-enab...@googlegroups.com <mailto:public-transport-enabler-discuss%2Bunsu...@googlegroups.com>.
> > For more options, visithttps://groups.google.com/groups/opt_out.
>
> --
> You received this message because you are subscribed to the Google Groups "public-transport-enabler-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to public-transport-enabl...@googlegroups.com <mailto:public-transport-enabler-discuss%2Bunsu...@googlegroups.com>.

paras...@googlemail.com

unread,
Oct 28, 2014, 8:25:45 AM10/28/14
to public-transport...@googlegroups.com
Hallo,

erst mal vielen Dank für das mühselige entschlüsseln des Binärformats!

Ich versuche gerade ein Python-Script zu schreiben, das die Verbindungen usw. aus dem Binärformat holt. Dazu verwende ich die url der Bahn ( http://reiseauskunft.bahn.de/bin/query.exe/dn? ).
Mit Hilfe der HAFAS-binär Tabelle konnte ich schon den globalen Header, den erweiterten Header sowie die String Tabelle usw. auslesen (die anderen habe ich noch nicht probiert).
Leider habe ich keine Ahnung, wie ich an die Verbindungs-Übersicht komme. In den Headern scheint es ja keinen Pointer auf die Tabelle zu geben oder steht die immer an einer bestimmten Adresse / Stelle? Oder komme ich über einen anderen Weg an die Verbindungen?
Reply all
Reply to author
Forward
0 new messages