RoadHog: Veröffentlichen

Diese Seite beschreibt die RoadHog-CGI-Skripte (in Perl geschrieben).

Design-Plan

Die CGI-Skripte und der Compiler arbeiten eng zusammen; vieles, was der Compiler macht, könnten theoretisch auch die Skripte machen. Man könnte sogar auf den Compiler ganz verzichten und jedes kleinste bißchen Inhalt dynamisch erzeugen.

Mein Ziel war es, so viel wie möglich statischen Inhalt zu erzeugen und das CGI-Skript so einfach wie möglich zu halten. Auf diese Weise minimiere ich den Ressourcenverbrauch auf dem Server, der das CGI betreibt, und er kann dann viele Anfragen gleichzeitig effizient handhaben. (Dieses Ziel hat allerdings nicht verhindern können, daß das CGI auf über 1.000 Zeilen angewachsen ist...)

Für jede hereinkommende Anfrage macht das CGI nur eine Datei auf - die Steuerdatei, eine simple Textdatei, die einfach eingelesen und interpretiert werden kann. Oft muß sie nicht einmal bis zu Ende gelesen werden.

Hier ist die Steuerdatei für eine sehr kurze Reise:

Shieldaig:Lochcarron::A896:4
256:192:mm:1200:1100:40:43:[einige Auslassungen]
tiny:small:medium:large
tiny:small:medium:large:huge

01.jpg:217:863:31x8:N57°31.43':W005°38.74':989162962:38:191
02.jpg:217:864:31x8:N57°31.22':W005°38.78':989162993:51:236
03.jpg:217:866:31x8,32x8:N57°31.04':W005°38.89':989163019:55:171
04.jpg:216:868:31x8,32x8:N57°31.00':W005°38.86':989163024:55:163

You are at a junction.
d:1.0::360:A896:Lochcarron:kenmorejunction-shieldaig:f7f4

Am Anfang stehen ein paar Konfigurationsinformationen - woher die Reise kommt, wohin sie geht, auf welche Straße usw. - und Informationen über die benutzte Karte und die verfügbaren Bildgrößen. Danach kommt für jedes Foto eine Zeile, die die Pixelposition, die betroffenen Kartenabschnitte, die Koordinaten, Zeit, Geschwindigkeit und Richtung enthält. Am Ende gibt es eine Statusmeldung und eine Liste der möglichen weiteren Verbindungen (in diesem Fall nur eine).

Das reicht schon aus, damit das CGI-Skript für jedes Foto dieser Reise die korrekte HTML-Seite erzeugen kann.

Der rote Punkt

Im Standardmodus erzeugt das CGI-Skript eine komplette HTML-Seite für jedes Foto. Die Karte, die neben dem Foto gezeigt wird, besteht aus fünf Zeilen und fünf Spalten von kleinen Bildchen; dort, wo der rote Punkt für die aktuelle Position sichtbar sein soll, werden die speziellen Kartensegmente mit vorgezeichnetem roten Punkt verwendet, die der Compiler bereitgestellt hat. Beispielsweise wäre das Karten-Stück in der Mitte des 5x5-Ausschnitts für Bild 2 dieser Reise Zeile 31, Spalte 8 mit dem roten Punkt an Position 217;866 (Dateiname: 31x8+217+866.gif). Für das dritte Bild sind zwei spezielle Kartenausschnitte nötig, 31x8+217+866.gif und 32x8+217+866.gif, weil der rote Punkt hier auf der Grenze zwischen zwei Kartenabschnitten liegt. Die Steuerdatei gibt immer nur das oder die zentralen Kartenstücke an; den Rest sucht sich das CGI-Skript selbst zusammen.

Es gibt auch einen CSS-Modus, in dem das CGI auf die speziellen Kartenausschnitte mit eingezeichneten roten Punkten verzichtet und stattdessen CSS-Poistionierung benutzt, um ein "roter-Punkt-Bild" an die Stelle zu setzen, wo es hingehört. Das kostet weniger Bandbreite, und wir können das "rote-Punkt-Bild" auch etwas variieren, je nach Richtung, in die gefahren wird.

Der Nachteil dieses Standard-Modus ist, daß viele Browser die Seite "löschen", bevor sie die nächste anzeigen, und dadurch kann ein unangenehmes Flackern entstehen. (Der Opera-Browser kriegt das allerdings prima ohne Flackern hin.)

Frame-Modus

Wenn der Frame-Modus eingeschaltet wird, läuft das Skript zweimal - einmal, um das "Frameset" einzurichten, und ein zweites Mal mit seiner Ausgabe in einem unsichtbaren Frame (dem Steuerframe). Das Skript wird nun nicht mehr bei jedem Refresh eine neue Seite aufbauen, sondern nur einen neuen Satz Javascript-Befehle an den Steuerframe schicken, der dann damit die anderen Frames bestückt. Das ist effizienter, als jeden Frame einzeln "reloaden" zu lassen.

Dieses Vorgehen bedeutet aber auch, daß der Frame-Modus nicht ohne Javascript auskommt.

Java-Modus

Der Java-Modus funktioniert fast wie der Frame-Modus, mit dem Unterschied, daß der zentrale Bereich mit der Karte und dem Foto nun ein einziger Frame ist, in dem ein Java-Applet sitzt (der Quelltext ist im RoadHog-Source-Download enthalten). Das CGI-Skript schickt die Ausgabe weiterhin an den unsichtbaren Steuerframe, aber anstatt einen neuen Inhalt für den Karten- und Bilderframe zu übermitteln, werden nun aus dem Javascript-Programm einige Methoden des Applets aufgerufen, um eine neue Karte und ein neues Foto zu laden. Dadurch entfällt das Flackern im Karten- und Fotobereich.

Preload und Bilder-Cache

Damit auf langsamen Leitungen keine Zeit vergeudet wird, schaut das CGI-Skript immer einen Schritt in die Zukunft und überträgt ein kleines Javascript-Programm, das, nachdem alle Bilder der aktuellen Seite fertig geladen sind, bereits das Foto und die neuen Kartenausschnitte für die nächste Seite lädt. Auf diese Weise sollten sich diese Bilder bereits im Browser-Cache befinden, wenn dann schließlich die nächste Seite angezeigt wird. Das geht natürlich nur, wenn der Browser auch wirklich "merkt", daß er die angeforderten Bilder schon geladen hat - sonst ist das ganze bloß eine Verschwendung von Bandbreite. (Wenn Javascript ausgeschaltet oder nicht verfügbar ist, wird die Preload-Funktion ignoriert, was auch nicht weiter schadet.)

Auch die Karten-Anzeige verläßt sich auf ein vernünftiges Bilder-Caching durch den Browser; wenn der Browser sich die Bilder "merkt", müssen maximal eine neue Zeile und eine neue Spalte von Kartenabschnitten nachgeladen werden (9 Bilder) und kein gesamter Ausschnitt (das wären 25 Bilder). Die Ausnahme davon ist das Java-Applet, denn das merkt sich seine Bilder selbst.

Das Such-Skript

Das Such-CGI kann entweder nach einem geografischen Ort (nach Koordinaten) oder nach einem Ortsnamen suchen. Beide Modi brauchen dafür eine spezielle Textdatei, die vom Compiler erzeugt wird. Die Datei enthält eine Liste aller Reisen mit einzeiliger Beschreibung, und danach eine Liste von Koordinaten (oder Ortsnamen) mit Verweisen auf diese Reisen. Ein Beispiel aus location.txt:

252c:Journey from North Erradale to Melvaig 
ae83:Journey from Inverlael to Blarnalearoch
86dc:Journey from North Erradale to Gairloch / Melvaig
f207:Journey from Kerrysdale to Kinlochewe
99e6:Journey from Badcaul to Badluarach
[...]

-5.812468577402863:58.15879941547619:59249.58824709085:111120.0
34263:0:209740:923408:97
34188:82:209663:923329:97
34180:88:209654:923324:97
34108:284:209574:923130:97
[...]

Die Liste der Reisen besteht nur aus den Journey-IDs und einer kurzen Beschreibung. Danach kommt eine Leerzeile, eine Zeile mit Koordinaten-Umrechnungsdaten, und dann folgt pro Foto eine Zeile mit Koordinaten.

Die Foto-Zeilen enthalten zwei Koordinatenpaare; das erste sind "Meter von der oberen linken Ecke des abgedeckten Bereichs", nach einer simplen Formel ausgerechnet: ein Längengrad = 111120m, ein Breitengrad = 111120 * cos (durchschn. Längengrad). Das reicht aus, um die einfachen Entfernungsberechungen zu machen, die das Skript braucht. Das zweite Paar sind die Koordinaten im "British Grid". Das Suchskript verwendet das erste Paar, wenn jemand nach Länge und Breite sucht, und das zweite, wenn nach British Grid-Koordinaten gesucht wird; so spare ich mir die Umrechnung in Perl. Der fünfte Wert auf jeder Zeile ist ein Verweis auf die entsprechende Reise - 97 heißt hier "die Reise aus Zeile 97".

Die Datei places.txt fängt genauso an, aber nach der Leerzeile geht es so weiter:

Dundonnell River::27,63
Black Water::29,131
Contin::36,83,114,130
Loch Carron::65,120
Loch Bad á Chrótha::11,15
Badachro::11,15
[...]

Das ist einfach eine Liste von Begriffen, die entweder aus den Namen der Start- und Zielknoten der einzelnen Reisen gewonnen wurden oder in den "via"-Tags der zugehörigen Kanten erwähnt waren. Hinter jedem Begriff stehen wieder Verweise auf die Reisen, zu denen er gehört. Das Suchskript benutzt das String::Similarity-Modul, um aus diesen Begriffen diejenigen auszuwählen, die dem ähnlich sehen, was der Benutzer eingegeben hat.

Zurück zum Index


  Frederik Ramm, 2001-05-24