Kartografische und horizontale Darstellung der Eisenbahn-Topologie

(Mit Topologie versteht man bei der Eisenbahn, diejenigen Daten des Netzes, die dessen Befahrbarkeit bestimmen inklusive Zusatzinformationen für den Fahrplan, zB Ortsnamen.)

Siehe auch ‹Brauchbare Darstellung eines Eisenbahnnetzes›

 

 

EINLEITUNG

Dieses Papier beschreibt eine sinnvolle «Manipulation der Koordinaten» um das Eisenbahnnetz gemäss UNO sinnvoll darzustellen.

Ich beschränke mich hier auf die Aspekte der Verzerrungen und lasse die üblichen Grafikfunktionen wie Schieben, Zoomen, Picken mit der Maus, Farbgebung und eventuell anderes weg.

Dieses Papier hat 4 Teile mit insgesamt 23 Schritten resp. Funktionen (und einem Nachtrag). Weil sich herausgestellt hat, dass die Datenorganisation für eine gute Verzerrung das Wesentliche ist, ist nicht bloss die Mathematik des Algorithmus beschrieben, sondern der ganze Ablauf von der Eingabe des Benutzers bis fast zum Bild auf dem Schirm, dh bis zu Koordinaten, die routinemässig auf Schirmkoordinaten umgerechnet werden können. Die Datenorganisation ist auch der Teil, der am aufwendigsten zu programmieren ist. Er wird mit Vorteil von der Art der Auswahl eines bestimmten Teils des Netzes durch den Benutzer unterstützt.

Weil es nicht zwingend ist, alle Schritte implementiert zu haben, um schon einen Gewinn zu haben, schlage ich nachstehend ein phasenweises Vorgehen vor.

Im ersten Teil wird das sogenannte Skelett entwickelt, an dem sich die ganze grafische Darstellung orientiert. Wir benutzen dazu die Linien, die zum Glück auf den Gleispunkten vermerkt sind. Das Skelett ist dann eine Folge von zusammenhängenden Gleiskanten mit ein paar Zusatzinformationen.

Im zweiten Teil werden die Positionen aller darzustellenden Punkte so errechnet und so abgespeichert, dass die Verzerrung im dritten Teil effizient ausgeführt werden kann. Das Skelett wird zu einem Polygonzug verdichtet, dann folgen die Punkte, die neben dem Skelett liegen, ‘neben‘ quer zur Fahrrichtung verstanden. Diese kennen ihre Position in Bezug auf einen Punkt des Polygonzuges. Weiter enthält Teil 2 eine Korrektur des Skeletts, die sachlogisch zu Teil 1 gehört, die aber dort wegen fehlender Daten noch nicht ausgeführt werden kann. Der zweite Teil ist der aufwendigste Teil, deshalb muss hier am meisten auf die Performance geachtet werden.

Im dritten Teil werden die Positionen, die bis dahin letztlich lediglich die Landeskoordinaten ergeben würden, quer zur Fahrrichtung gespreizt und längs dazu geschrumpft, gesteuert durch zwei verstellbare Parameter, verstellbar, weil nicht jedes Bild dieselbe Verzerrung benötigt.

Im vierten Teil folgen denkbare manuelle Eingriffe, einerseits um das resultierende Bild zu verbessern, andererseits um eine abstrakte Darstellung zu erlangen.

Der Nachtrag streift noch die besonderen Tücken, die in dem Fall die Umrechnung auf Schirm-Koordinaten mit sich bringt.

Um schnell zu überprüfbaren Resultaten zu kommen, ist es ratsam, zuerst eine beträchtlich gekürzte Version zu erstellen: Von Teil 1 soll in Phase A nur ein Schritt, nämlich Schritt 1.3 implementiert werden. In Teil 2 sind nur die ersten beide Schritte zwingend, die Shift-Sachen (Schritte 2.3 und 2.4) gehören erst zur vierten Phase, ebenso Schritt 2.7. Schritt 2.6 ist billig, kann aber bei einer ersten Visualisierung problemlos fehlen, er kann deshalb in Phase B folgen.

Mein Vorschlag:

Phase A:   Schritt 1.3

                  Schritte 2.1 und 2.2

                  Die kartografische Darstellung von Schritt 3.1

                  Die kartografische Darstellung von Schritt 3.2

Phase B:   Schritt 2.4

                  Schritt 3.3

                  Schritt 1.4

                  Schritt 2.5

Phase C:   Die horizontale Darstellung von Schritt 3.1

                  Die horizontale Darstellung von Schritt 3.2

                  Schritt 3.4

                  Schritt 1.2

Phase D:   Schritte 2.3 und 2.6

                  Schritt 1.1

Phase E:    Funktionen von Teil 4 nach Bedarf

 

 

TEIL 1: SKELETT

 

Schritt 1.1: Wahl des Bildbereichs

Die Auswahl des Bildbereichs geschieht über die Linien. Wir gehen davon aus, dass eine Linie keine Verzweigung hat (sollte dem tatsächlich irgendwo nicht so sein, werden wir uns etwas einfallen lassen). Die Mindestangabe ist also eine Liniennummer.

Will man Strecken und Bahnhöfe von mehreren Linien sehen, so gibt man mehrere ein. Linien können aber auch zu gross sein, also kann man jede eingegebene Linie mit einem Anfangs- und einem Endpunkt einschränken, es reicht wohl mit dem BP (=Betriebspunkt). Die Eingabemaske hat also eine Listenform mit 3 möglichen Feldern pro Listeneintrag, zB:

Liniennummervon-BPbis-BP
600BELRIB
630  
631 PINT
. . .. . .. . .

Dabei sind eigentlich nur die Liniennummern obligatorisch. Da die Liniennummer einem Benutzer vielleicht nicht geläufig ist, kann die Maske anbieten, bei Eingabe eines BPs oder zwei BPs die an diesem BP oder an diesen BPs vorkommenden Linien vorzuschlagen bzw., wenn es nur eine ist, gleich einzutragen. (Solche Kommoditäten sind meiner Meinung nach billig zu haben.)

Die Linie zuoberst bildet den Hauptast, darunter folgen die Nebenäste in abnehmender, durch die Reihenfolge definierter Hierarchie.

Allerdings lohnt es sich nicht, den Anfangs-BP des Hauptastes algorithmisch zu bestimmen, deshalb ist für die erste Linie auch der von-BP obligatorisch. Auch sonst soll nicht das Maximum an algorithmischen Möglichkeiten implementiert werden. Es reicht, wenn alles irgendwie angezeigt werden kann.

Die Bedeutung ist grösstenteils evident. In obigem Beispiel wird Linie 600 zwischen Bellinzona und Rivera-Bironico, die ganze Linie 630 und die Linie 631 von ‘‘Anfang‘‘ bis Pino-Tronzano verlangt, der ‘Anfang‘ in Anführungszeichen, weil das ist einfach der Punkt, wo man auf der Linie 600 oder auf der Linie 630 auf die die Linie 631 stösst. Das stimmt in diesem wie vielfach mit dem wirklichen Anfang überein, aber das ist nicht ganz immer so.

Auf diese Weise können natürlich auch nicht zusammenhängende Gebilde eingegeben werden; das soll verboten sein, konkret: es erscheint eine Fehlermeldung. (Andernfalls müssten zwei unabhängige Bilder erstellt werden, das ist meiner Meinung nach zu viel Aufwand für den wenigen Nutzen.)

Auch sonst ist der Benutzer nicht ganz frei, in Bezug auf seine Eingabe: BPs, die keine Weichen haben, zB gewisse Haltestellen, oder nur schon nicht auf allen Gleisen Weichen, sind als von- und bis-BPs ungeeignet; es wäre aufwendig, das abzufangen (siehe Schritt 1.3).

 

Schritt 1.2: BP-Mengen mit Start-BPs

Um allzu wilde Suchen über alle Gleiskanten zu umgehen, ist in Schritt 1.1 ein Anfangs-BP verlangt worden. Es ist auch so noch umständlich genug, wenn auch nicht schwierig: Zu einem BP gibt es in Praxis immer nur eine geringe (<10) Zahl von BP-Verbindungen. Eine BP-Verbindung hat mindestens ein Streckengleis, dieses verweist auf eine Gleiskante, deren Gleispunkte die Liniennummer tragen. Wir können also von einer Liniennummer der BP-Verbindung sprechen. Es gibt zwar Fälle, wo verschiedene Liniennummern vorkommen, die am häufigsten vorkommende Liniennummer ist die richtige.

So findet man mindestens eine zur Line gehörige BP-Verbindung und am andern Ende wieder einen BP, von dem (meistens) wieder eine oder mehrere BP-Verbindungen weggehen (abgesehen von der, mit der wir gekommen sind). Repetitiv sammelt man so alle BPs einer Linie auf, entweder bis an deren Ende oder bis und mit dem angegebenen bis-BP. Der letzte BP bildet ganz simpel den End-BP. Wahlmöglichkeiten unterwegs soll es nicht geben, weil Linien unverzweigt sein müssen.

Hingegen können vom ersten BP 2 BP-Verbindungen unserer Linie weggehen, in dem Fall folgt man der Richtung der BP-Verbindung, ist das nicht eindeutig, wird der Benutzer gefragt.

Dabei stösst man auch auf die Start-BPs von Nebenästen, entweder auf Grund der von-BP-Eingabe bei der Auswahl, oder auf Grund der Liniennummer der BP-Verbindungen; geschieht dies mehrmals, so wird nur das erste Auffinden bewahrt.

Nach dem Hauptast werden für die Nebenäste in der hierarchischen Reihenfolge genau gleich abgearbeitet und so die BP-Mengen und der End-BP bestimmt. Auch bei diesen können am Anfangspunkt 2 BP-Verbindungen der Linie weggehen (zB in Rotkreuz). Bei den Nebenästen ist beiden zu folgen. Das ergibt je nachdem 2 Äste (aus nur einer Eingabezeile), es sei denn, der angegebene von- oder bis-BP entspreche dem Start-BP, worauf der Ast, der nicht zum eventuell zweiten angegebenen von- respektive bis-BP führt, fallen gelassen wird, oder, wenn diese zweite Angabe fehlt, derjenige, dessen BP-Verbindung beim Start-BP in die ‘‘falsche‘‘ Richtung zeigt.

Das Resultat dieses Schrittes ist für jeden Ast eine BP-Menge, ein Start-BP und ein End-BP, wobei jeder Start-BP eines Nebenastes auf dem Hauptast oder einem ranghöheren Nebenast liegt.

 

Schritt 1.3: Skelettbau des Hauptastes

Nun gilt es einmal das sogenannte Skelett mit dem Ursprung zu erstellen. Der Ursprung ist ein Punkt versehen mit realen Koordinaten, von dem aus die Zeichnung erstellt wird. Die übrigen Punkte sind mittels des Skeletts datenmässig so auf den Ursprung bezogen, dass dann relativ leicht eine vernünftige Verzerrung eingebaut werden kann.

Entweder gibt uns der Benutzer eine Gleiskante  – und kann so den Bildaufbau eventuell günstig beeinflussen –  oder wir bestimmen sie algorithmisch. Da es schwierig ist, die wirklich beste Kante zu finden, begnügen wir uns mit einer vielfach vernünftigen Lösung und einem ‘‘fixierten Zufall‘‘, dh das Resultat ist inhaltlich zufällig, ergibt aber bei jedem Aufruf dasselbe Resultat.

Haben wir nur einen BP darzustellen, nehmen wir die Gleiskante, auf der die Gleisnummer liegt, die im ganzen BP die niedrigste Kantennummer trägt. Ansonsten starten wir mit der ersten Verbindung beim Start-BP. Von dieser nehmen wir das Streckengleis, bei mehreren, das mit der tieferen Identifikation und kommen so zu einer Gleiskante.

Dieser ersten Gleiskante folgen wir mir in beiden Richtungen, gehen von Gleiskante zu Gleiskante, immer der Linie folgend und, wenn immer möglich, in gerader Richtung über die Weichen hinweg.

‘In gerader Richtung über die Weichen hinweg‘ heisst präzise und mathematischer mit den Tupeln (Weichenseite, Weichenzugang) ausgedrückt:

            (0, 0)    ->    (1, 1) oder (1, 0)

            (0, 1)    ->    (1, 1)

            (0, 2)    ->    (1, 2)

            (1, 0)    ->    (0, 0)

            (1, 1)    ->    (0, 0) oder  (0, 1)

            (1, 2)    ->    (0, 2)

            wobei (0, 0) nie gleichzeitig mit (0, 1) und (1, 1) nie gleichzeitig mit (1, 0) vorkommt.

In der einen Richtung kommen wir mit der Zeit zum End-BP. Damit steht das Verfahren vor dem Stopp: Darauf werden nur noch Gleiskanten aneinander gehängt, bis der jenseitige Gleisknoten einen andern Betriebspunkt gehört oder die Liniennummer wechselt, Letzteres kann durchaus mitten auf der Gleiskante passieren. Diese Gleiskante kommt noch mit, dann wird das Verfahren an dieser Stelle beendet.

In der andern Richtung steht das Verfahren gleich von Anfang an auf Stopp, im Übrigen wird gleich verfahren, mit dem kleinen, später wichtigen Zusatz, dass der letzte Punkt zum Ursprung des Astes erklärt wird.

Nun folgen noch zwei Komplikationen:

  1. Es kann sein, dass wir von (1, 2) kommen und kein (0, 2) vorfinden, weil wir auf einer einfachen Weiche von der stumpfen Seite her über Ablenkung kommen. Notgedrungen folgen wir (1, 2)  ->  (0, 0). Diese Ablenkung führt zu einer ‘Shift‘ genannten Zusatzinformation auf den letzten Punkten vor der Weiche: Um diesen Shift zu berechnen, fehlen uns in diesem Teil allerdings die Gleispunkte auf den Gleiskanten. Deshalb müssen wir das auf Schritt 2.3 verschieben, und uns damit begnügen, die Tatsache des Überganges über Ablenkung von der stumpfen Seite her zu merken.
  2. Nun können wir noch auf einem Gleisende landen oder auf eine andere Liniennummer stossen, bevor wir den End-BP erreicht haben. Da bleibt uns wohl nichts anderes übrig, als ein Backtracking eine Weiche zurück, dort das alternative Gleis verwenden, dh über Ablenkung fahren, und uns, analog oben, den Übergang zu merken.

(Das ist vielleicht zu aufwendig für einen Fall, der kaum je vorkommt. Billiger ist es vielleicht, die Sackgasse zu melden und den Benutzer zu Hilfe zu rufen. Zuerst warten wir, ob der Fall überhaupt vorkommt, also nur eine kleine Meldung.)

Anmerkung 1: Der Shift ist insofern nötig, als er auch für die im nächsten Schritt eingeführten Seitenäste gebraucht wird. Machen wir ihn nicht, führt die Querverzerrung des dritten Teils dazu, dass der Stamm aussieht wie sonst die Ablenkung und die Ablenkung fast wie normalerweise der Stamm.

Anmerkung 2: Chambrelien lässt   n i c h t   grüssen. Die Strecke 223 geht von Neuchâtel-Vauseyon (bif) nach Chambrelien und von Chambrelien nach La Chaux-de-Fonds hat die Strecke die Nummer 224. Es gibt wohl keine Linie mit Spitzkehre bei den SBB. (Die CJ zwischen Saignelégier und Glovelier haben wir nicht auf Gleiskanten-Niveau.)

 

Schritt 1.4: Skelettbau der Seitenäste

Die Seitenäste werden in ihrer hierarchischen Reihenfolge abgearbeitet. Der eigentliche Skelettbau unterscheidet sich nicht von dem des Hauptastes, anders ist nur die Suche nach dem Ursprung. Dieser muss bei jedem Seitenast ein Punkt des Hauptastes oder eines hierarchisch höher stehenden Seitenastes sein, allerdings nicht zwingend eine Weiche, normalerweise ist es ein Gleispunkt auf einer Gleiskante, die ebenfalls nicht zwingend zum Skelett gehört, aber zum Body, siehe Teil 2.

Durch Schritt 1.2 ist garantiert, dass der Start-BP des zu konstruierenden Seitenastes zum Hauptast oder zu einem hierarchisch höher stehenden Seitenast gehört. Wir suchen die Gleiskanten dieses BPs und diejenigen von diesem BP zu einem andern oder von einem andern zu diesem BP nach Gleiskanten ab, die beide Liniennummern in ihren Gleispunkten haben. Bei mehreren wählen wir die mit der kleinsten Nummer. Der Ursprung des Seitenastes ist der Punkt, der den Punkten der Linie des Seitenastes am nächsten liegt, aber selbst noch zum Hauptast resp. hierarchisch höher stehenden Seitenast gehört.

Finden wir keine solche Kante, so suchen wir unter den Knoten des BPs einer, bei dem Kanten beider Linie zusammenstossen, wählen bei mehreren den mit der kleinsten Nummer und haben damit unseren Ursprung. In diesem Fall wäre eine Warnung an den Benutzer angebracht, weil die Querverzerrung bei diesem Ursprung nicht den gewünschten Effekt ergeben wird.

Leider hat sich gezeigt, dass die Definition der Linien durch DfA (= Datenbank feste Anlagen) nicht immer unseren Wünschen entspricht. Verschiedentlich ist der Linienwechsel nicht dort auf der Kante, wo der gemeinsame Gleiskörper sind in zwei Gleiskörper aufteilt, oder es gibt in einem grösseren Bahnhofgebiet (zB ZVB) zusätzliche Linien, die wenig motiviert sind, an andern Orten zB Luzern, stehen Abstellgruppen schräg zum Hautstrang und sollten für unsere Zwecke eine eigene Linie haben. Deshalb werden in Teil 4 manuelle Korrekturen vorgeschlagen.

 

Resultat von Teil 1

Wir haben ein Skelett bestehend aus hierarchisch geordneten Ästen. Jeder Ast hat eine Liniennummer und einen Ursprung und besteht im Übrigen aus einer geordneten Folge von Gleisknoten und Gleiskanten mit einigen Zusatzinformationen:

–     BP der Gleisknoten

–     Koordinaten der Gleisknoten

–     Streckenkilometer der Gleisknoten

–     Länge der Gleiskanten

–     Richtung der Gleiskante in Bezug auf den Ursprung, also ‘weg‘ oder ‘hin‘ zum Ursprung

–     Typ des Übergangs: ‘Stamm‘, ‘von Ablenkung‘, ‘nach Ablenkung‘

 

 

TEIL 2: BODY

Nun gilt es, aus dem Skelett einen Body zu machen. Dieser enthält alle Punkte des darzustellenden Gebietes. Die Datenstruktur für die Punkte soll so sein, dass nachher die Verzerrung einfach (und einigermassen effizient) ausgeführt werden kann.

 

Schritt 2.1: Verdichtung zum Polygonzug

Zuerst fügen wir die Gleispunkte in das Skelett ein. Wir gehen Ast für Ast vor (die Reihenfolge spielt ausnahmsweise keine Rolle).

Wir beginnen beim Ursprung und folgen den Gleiskanten in der vorgegebenen Abfolge. Auf den Gleiskanten liegen Gleispunkte einerseits mit einer Position auf der Gleiskante, andererseits mit Koordinatenangaben. Unter Berücksichtigung der Richtung der Gleiskanten bekommen wir pro Ast eine Folge von Punkten mit Koordinaten, wobei der erste Punkt der ersten Gleiskante der Ursprung ist.

Jeder Nicht-Ursprungspunkt hat einen Abstand zum Vorgänger (Differenz in der Position auf der Gleisachse; sie ist nie negativ), eine Differenz in S-N-Koordinaten und eine Differenz in W-E-Koordinaten. Alle drei Werte sind denkbar leicht zugänglich und sollen ‘‘auf dem Punkt‘‘ als (Dx, Dy) gespeichert werden.

Gleisknoten werden theoretisch wie Gleispunkte behandelt. Häufig werden sie mit einem solchen örtlich zusammenfallen. Eine Kante von Länge 0 macht aber Schwierigkeiten im nächsten Schritt, deshalb sollte hier eine andere Lösung gefunden werden, zB indem einer der doppelten Punkte wie ein Punkt vom nächsten Schritt behandelt wird, oder der Gleispunkt wird einfach gestrichen.

Somit haben wir für jeden Ast einen Polygonzug, dessen Verlauf vom jeweiligen Ursprung her festgelegt ist und das Eisenbahnnetz kartografisch darstellen könnte.

Wegen Gebrauch im nächsten Schritt speichern wir auf jedem Gleispunkt noch den Streckenkilometer.

 

Schritt 2.2: Übrige Gleiskanten und deren Gleispunkte

Nun gilt es die übrigen Gleiskanten der abzubildenden Betriebspunkte in die Datenstruktur aufzunehmen. Auf Grund der Menge der BPs bekommen wir alle dazugehörigen Gleisknoten und mit diesen alle dazugehörigen Gleiskanten, diese sollen jeweils dabei sein, wenn wenigstens einer ihrer Knoten zu einem BP in der BP-Menge gehört. Die Punkte sollen Gleiskante per Gleiskante, Gleispunkt nach Gleispunkt in aufsteigender Position durchgegangen werden. Auf diese Weise kann sehr einfach das Feld ‘vorgängiger Gleispunkt‘ eingefüllt werden, das zum Zeichnen der Gleiskante notwendig ist.

Der Platz dieser Punkte soll mit einer Position auf dem Polygonzug und einem gerichteten  – das heisst mit Vorzeichen versehenen –  Abstand zum Skelett  beschrieben werden. (Das ist wohl der performancemässig kostspieligste Schritt, deshalb lohnen sich einige Gedanken für ein einigermassen effizientes Vorgehen.)

Wir brauchen dazu die 2 nächstliegenden Punkte auf dem Polygonzug, die einander unmittelbar folgen. Logisch am simpelsten ist es, zu allen Punkten den Abstand auszurechnen und zu vergleichen, der Aufwand wäre aber gross. Ich schlage deshalb Folgendes vor: Wir nehmen die Kilometerangabe des Gleisknoten/punkten und suchen ausgehend vom selben Kilometer auf dem Polygonzug in beide Richtung. Sobald von einem Punkt zum nächsten der Abstand ansteigt, brechen wir die Richtung ab. Im Normalfall sind so schon die ersten Punkte links und rechts die nächsten und wir brauchen nur je einen Schritt, um festzustellen, dass der Abstand zunimmt. Im Übrigen nehmen wir selbstverständlich nicht den Abstand sondern das Quadrat davon, das kostet weniger Rechenzeit.

Der Rest ist Mathematik: Wenn die gefundenen Punkte auf dem Polygonzug A und B heissen, in dieser Reihenfolge im Polygonzug aufeinander folgen und P der einzufügende Punkt ist, dann beziehen sich Dx und Dy von B auf A, ich bezeichne sie mit Bx für Dx und By für Dy . Für P können wir diese Deltas  – Px und Py –  in Bezug auf A auf Grund der Koordinaten einfach und effizient berechnen. Dann kann der Weg von A nach P, wo immer P ist, beschrieben werden als Teilweg auf der Kante A -> B und Teilweg senkrecht dazu, und beide Teilwege aufgelöst in x- und y-Koordinaten:

Px   =   K . Bx  –  C . By    und    Py   =   K . By  +  C . Bx    mit   K := (BxPx + ByPy) / L2  und 

C := (BxPy – ByPx) / L2 ,  wobei L2 der Abstand A -> B im Quadrat ist.

Von A nach A + (K . Bx, K . By) hat offensichtlich die Richtung von A->B, von da gehen wir weiter mit dem Vektor (-  C . By, C . Bx), und der verläuft in die im Gegenuhrzeigersinn gedrehte Richtung von A->B. Daraus resultiert: C > 0 => P links von A->B und C > 0 => P rechts von A->B.

Auf dem Punkt P sind die je 2 Komponenten der 2 Teilwege zu seinem Bezugspunkt A abzuspeichern, weil bei der Verzerrung in Teil 3 der erste Teilweg der Längsverzerrung und der zweite Teilweg der Querverzerrung unterliegen werden.

Das funktioniert auch, wenn P nicht im eigentlichen Sinn über (oder unter) der Kante A -> B liegt, K ist dann einfach entweder grösser als 1 oder kleiner als 0. Das Zeichen von C gibt an, ob P links (C > 0) oder rechts (C < 0) von der gerichteten Kante A -> B liegt. Das brauchen wir im nächsten Schritt bei den Übergängen über Ablenkung. Deshalb ist das Zeichen von C bei den Punkten zu speichern.

 

Schritt 2.3: Shift berechnen

Jetzt sind wir soweit, dass wir den Shift berechnen können. Der Shift betrifft alle Gleispunkte und Gleisknoten, die in der Nähe einer über Ablenkung ‘‘befahrene‘‘ Weiche liegen.

Wir nehmen nacheinander jeden Gleisknoten G, bei dem ein Übergang über Ablenkung gemeldet ist und folgen den ersten Punkten der Gleiskante, die an dieser Stelle dem Weg über Stamm entspricht. Wir legen eine Liste an mit den Punkten auf dieser Gleiskante bis zum ersten Punkt, der mindestens 50 m Abstand von G hat, das kann über die Kante hinaus in die nächste gehen. Damit es nicht zu kompliziert wird, soll nur in die nächste Kante hinausgegangen werden, wenn an dieser Weiche eine ‘‘gerade‘‘ Fortsetzung möglich ist. Andernfalls wird von den letzten beiden Punkten her extrapoliert.

Wir notieren zu jedem dieser Punkte P den Abstand PL von G (Länge auf der Kante, nicht Dx und Dy) und den Abstand zum Polygonzug in kartesischen Komponenten, also (C . By, C . Bx) in den Bezeichnungen des vorangegangenen Schrittes, nachstehend mit (Px-Ab, Py-Ab) bezeichnet. Dazu nehmen wir das Zeichen von C, das bei allen gleich sein muss, um festzustellen, ob der Weg von links oder von rechts eingemündet resp. nach links oder nach rechts geführt hat.

Nun nehmen wir die Kante des Polygonzuges, die über Ablenkung verlief, das ist im einen Fall die vor G, im andern Fall die nach G, und folgen den ersten Punkten Q1, Q2, Q3, … auf dieser Kante von G weg, normalerweise bis und mit dem ersten Punkt mit QnL > 50 m, wobei QnL der Abstand von Qn zu G ist (Länge auf der Kante, nicht Dx und Dy).

Stossen wir vorher auf eine Weiche, so fahren wir auf der anschliessenden Kante fort, es sei denn, es folge ein weiterer Übergang über Ablenkung von/nach andern Seite (ob ‘von‘ oder ‘nach‘ spielt keine Rolle), abgesehen vom pathologischen Fall, dass wir am Ende unseres Gebietes sind und gar keine Kante folgt. In diesen Fällen stoppen wir die Suche nach Punkten.

Es sei: QnL* := max(QnL, 50).

Wir suchen in unserer Liste den Punkt S, bei dem SL <= QnL* und QnL* – SL minimal ist. Dann suchen wir den Punkt T, bei dem und TL >= QnL* und TL – QnL* minimal ist, oder, falls es das nicht gibt, dh Extrapolierung nötig wird, suchen wir den Punkt R mit maximalem RL < unter der Bedingung RL < SL (man beachte die scharfe Ungleichheit ); in letzterem Fall ist TL := 50 und Tx-Ab :=  Rx-Ab + (Rx-Ab – Sx-Ab) (50 – RL) / (SL-RL)  und

                           Ty-Ab :=  Ry-Ab + (Ry-Ab – Sy-Ab) (50 – RL) / (SL-RL)

Der absolute Shift für Punkt Qn ist dann in beiden Fällen in x- und y-Komponenten:

Qn:Abs-Sh(x) := [ (QnL* – SL) (- Sx-Ab)  +  (TL – QnL*) (- Tx-Ab) ] [1 / (TL-SL) ]    und

Qn:Abs-Sh(y) := [ (QnL* – SL) (- Sy-Ab)  +  (TL – QnL*) (- Ty-Ab) ] [1 / (TL-SL) ] .

Anmerkung: Die Bezeichnung ‘absoluter Shift‘ soll nicht zur Auffassung verleiten, es handle sich um Absolutbeträge. Diese haben ein Zeichen.

Nun muss das Resultat der Shift-Berechnung auf den Punkten Qn unserer Liste gespeichert werden. Da müssen wir die beiden Fälle leicht unterschiedlich behandeln. Wenn wir vom Spitz her über Ablenkung fahren, so ist bei unseren relativen Positionsangaben:

Q1:Shift(x) := Q1:Abs-Sh(x) und Q1:Shift(y) := Q1:Abs-Sh(y)   

Für n >1 gilt: Qn:Shift(x) := Qn:Abs-Sh(x)  – Qn-1:Abs-Sh(x)  und Qn:Shift(y) := Qn:Abs-Sh(y)  – Qn-1:Abs-Sh(y)

Selbstverständlich würde der absolute Shift ab dem zweiten Mal QmL >= 50 konstant, also ist es richtig, dass die Shifts der weiteren Punkte auf 0 bleibt.

Fahren wir vom Stumpf her über eine Ablenkung, so ist der zu speichernde Shift:

Qn:Shift(x) := Qn:Abs-Sh(x)  – Qn+1:Abs-Sh(x)  und Qn:Shift(y) := Qn:Abs-Sh(y)  – Qn+1:Abs-Sh(y)   solange Qn und

Qn+1 existieren. Im Übrigen: Qn-max:Shift := (0,0) und GShift(x) := – Q1:Abs-Sh(x) , GShift(y) := – Q1:Abs-Sh(y)

Sollte es vorkommen, dass innerhalb der 50 Meter eine weitere Ablenkung befahren, so wird im Fall des Seitenwechsels abgebrochen (wir haben auch keine Punkte mehr, siehe oben), und der neue Übergang über Ablenkung generiert keine Shifts, wird also von der Shift-Berechnung ausgeschlossen. Andernfalls werden die Shifts beider Übergänge unbeeindruckt berechnet und inklusive Zeichen einfach addiert.

Ob wir links oder rechts liegen, wird ebenfalls gespeichert, also normalerweise das Vorzeichen von C, bei Additionen das Zeichen von C des absolut grösseren Shift-Betrages.

Nachbemerkung: Vielleicht wäre es intelligenter, die 50 Meter anzuheben, dafür abzubrechen sobald der absolute Shift eine gewisse Grösse erreicht, zB 3 m. So laufen wir weniger in Gefahr, bei schnellen Weichen zu früh aufzuhören. Auch sonst könnte man noch einiges komplizierter gestalten, insbesondere die Fälle, wo Shifts sich überschneiden, weil ein Übergang von der Seite näher als 100 m (aber weiter als 50 m) auf einen Übergang nach der Seite folgt.

 

Schritt 2.4: Schrumpfabschnitte

An dieser Stelle ist es sinnvoll eine Vorbereitung für die Längsschrumpfung (Abschnitt 3.3) einzubauen. Die Gleiskanten des Skeletts werden (auf dem Haupt- und den Nebenästen) in Schrumpfabschnitte eingeteilt. Als Einteilungspunkt gilt jede Weiche und jedes Gleisende, genauer der Projektionspunkt von jedem Gleiskanten beendenden Element des Bodys.

(Theoretisch könnte man sich einige Schrumpfabschnitte sparen, wenn deren Summe 50 m nicht übersteigt, aber eine solche Komplikation gibt wohl völlig unlohnend viel Arbeit.).

 

Schritt 2.5: Übrige Punkte auf den Gleiskanten

Auf den Gleiskanten von UNO liegen einige Objekte, die man gerne auf dem Schirm sehen würde, als da sind: MitteAG, Signale, V-Schwellen, Gleisnummern, Codepunkte und eventuell noch mehr.

Diese haben alle eine Position auf der Gleiskante und können so zwischen zwei Gleispunkte/Gleisknoten ohne besonderen Aufwand linear interpoliert werden, zumal mit den Gleisknoten dafür gesorgt ist, dass an jedem Endpunkt einer Kante auch ein Punkt liegt. Das gilt alles sowohl auf den Gleiskanten des Polygons wie auch denjenigen der übrigen Gleisanten, es gibt bei Letzteren einfach ein paar Parameter mehr zu interpolieren, die Rechnung ist aber immer dieselbe.

Man beachte, dass auch die Shifts zu interpolieren sind und dass gespeichert werden muss, in Bezug auf welchen Gleispunkt/Gleisknoten sich die angegebenen Werte beziehen.

 

Schritt 2.6: Punkte neben den Gleiskanten

Der Betriebspunkt und damit sein Symbol hat eigene Koordinaten, diese geben in der Regel eine Position neben den Schienen an. Auch Perrons liegen zwischen den Gleissträngen, möglicherweise gibt es noch andere Objekte, die man gerne darstellen würde.

Normalerweise haben diese keinen Streckenkilometer, deshalb ist eine Positionierung nicht so einfach. Perrons haben nicht einmal Koordinaten. Man kennt den Betriebspunkt und meistens auch an welchem Gleis oder zwischen welchen Gleisen das Perron liegt. Das würde für eine individuelle Lösung Perrons zu zeichnen reichen, die Frage ist, ob sich das lohnt.

Betriebspunkte haben Koordinaten, man könnte sie also analog den Gleispunkten von Kanten ausserhalb des Polygons behandeln, oder eine individuelle Lösung suchen, oder sie einfach in unverzerrtem Abstand zum nächstliegenden Punkt zeichnen, aber den nächstliegenden zu finden ist wieder relativ viel Rechenpower für so wenig.

 

Resultat von Teil 2

Das Skelett wurde in Teil 2 zum Body erweitert. Zuerst hat es sich pro Ast zu einem Polygonzug verdichtet, danach kamen weitere Punkte dazu, sowohl auf den Gleiskanten der Polygonzüge, als auch daneben. Letztere stellen unter anderem die parallelen Gleise dar. Geblieben sind die verschiedenen Äste jeweils mit dem Ursprung auf dem Hauptast oder einem hierarchisch höheren Ast. Zusätzlich ist jede Gleiskante des Skeletts eingeteilt in Schrumpfabschnitte.

Wir haben also eine Liste von Ästen mit der Liniennummer als Identifikation und einer Ordnungszahl entsprechende der Einordnung in der Hierarchie. Zu jedem Ast gehört ein Polygonzug mit einem Ursprungspunkt. Im Weiteren haben wir eine Menge von Zusatzpunkten.

Ein Polygonzug besteht aus einer totalgeordneten Reihe von Punkten, die jeweils einen Gleisknoten oder einen Gleispunkt repräsentieren. Bei den Gleispunkten steht der BP und die Weichennummer (zum Anschreiben), bei allen Punkten stehen folgende Ortsinformationen:

–     Vorgängerpunkt (ausg. Ursprung des Hauptastes)

–     Nachfolgerpunkt, falls existent (nur der auf seinem eigenen Ast)

–     Dx und Dy zum Vorgängerpunkt

–     x-Shift und y-Shift, mit Anweisung ‘links‘ oder ‘rechts‘

–     Gleiskante zu der der Punkt gehört, bei Gleisknoten ist das die Gleiskante vorher

–     Position auf der Gleiskante

–     km auf der Linie (wird ab da nicht mehr gebraucht)

Der Nachfolgepunkt dient auch der Bezeichnung des Vereinigungspunktes bei Zyklen. Dabei muss der Vereinigungspunkt nicht auf dem Polygon liegen. In den andern Fällen ist der Nachfolgepunkt streng logisch redundant, er dürfte sehr nützlich für die Performance sein.

Bei den übrigen Punkten spielt der Polygonzüge keine Rolle, wohl aber die Astzugehörigkeit, damit nachher in Schritt 3.1 jeder Ast seinen Ursprung bereits positioniert hat. Auch die Gleiszugehörigkeit, genauer: die Zugehörigkeit zu einem Schrumpfabschnitt, muss gespeichert sein, wegen der Schrumpfung in Teil 3. Abgesehen von Informationen, die zum Anschreiben dienen (zB Weichennummern, Signalbezeichnungen, BP-Namen) müssen jedem Punkt folgende Ortsinformationen beigefügt sein:

–     Bezugspunkt

–     Astzugehörigkeit

–     Dx-längs, Dy-längs (das ist  K. Bx  und K . By aus Abschnitt 2.2 bzw. 2.4)

–     Dx-quer, Dy-quer (das ist  –  C . By und  C . Bx aus Abschnitt 2.2 bzw. 2.4)

–     Gleiskante zu der der Punkt gehört

–     Vorgängiger Gleispunkt

Der vorgängige Gleispunkt gibt an, wo Gleiskanten gezeichnet werden müssen. Ist das nicht der Fall, ist das Feld leer.

 

 

TEIL 3: DARSTELLUNG UND VERZERRUNG

 

Schritt 3.1: Kartografische und horizontale Darstellung von einem azyklischen Body

Mit dem Body ist es einfach, eine unverzerrte, kartographische Darstellung auf den Schirm zu bringen. Man beginnt mit dem Ursprung des Hauptastes und folgt den Punkten von dessen Polygonzug und addiert von einem Punkt zum andern die Dx und Dy; die Shifts werden da nicht berücksichtigt. Dann folgen die übrigen Punkte des Hauptastes mit Addition von Dx-längs, Dy-längs, Dx-quer und Dy-quer zu den Koordinaten des jeweiligen Bezugspunktes.

Als nächstes kommt der ranghöchste Nebenast, dessen Ursprung jetzt vorhanden ist, auf dieselbe Art und Weise dran, dann der nächst rangniedrigere usw.

Somit sind alle Punkte mit realen Koordinaten versehen, die nur noch auf Schirmkoordinaten umzurechnen sind.

Aus dem Body eine unverzerrte, horizontale Darstellung abzuleiten ist ebenfalls leicht. Das Durchscannen der Punkte ist gleich wie oben, anders sind nur die Summanden von einem Punkt zum nächsten:

  1. Für die Punkte des Polygons werden anstatt Dx jeweils die Länge zum vorherigen Punkt genommen (Dy fällt unter den Tisch). Der Shift ergibt hier eine y-Komponente, und zwar als positiver Summand wenn ‘links‘ und als negativer Summand wenn ‘rechts‘, der Betrag ist  (x-Shift2 + y-Shift2)0.5 .
  2. Für die übrigen Punkte gilt Analoges: In x-Richtung wird (Dx-längs2 + Dy-längs2)0.5 ,  in y-Richtung (Dx-quer2 + Dy-quer2)0.5  zur Position des Bezugspunktes addiert  – Punkt links –  respektive subtrahiert  – Punkt rechts – .

Anmerkung: Das kostet etwas mehr Performance als bis anhin wegen der Wurzeln. Allerdings steigt das nur linear mit der Anzahl Punkte, also braucht man sich hoffentlich keine Sorgen diesbezüglich zu machen.

Nebenäste müssen hier auf eine andere Zeile gesenkt oder gehoben werden, je nachdem, ob sie (auf dem Schirm) oberhalb oder unterhalb des Hauptastes liegen. Diese andern Linien zu finden, bzw. die horizontalen Niveaus gut zu verteilen, kann man natürlich beliebig ausgefeilt gestalten.

Ich schlage vor, nur die Nebenäste zu zählen, auf dem Schirm gleichmässig verteilt diese Anzahl Linien vorzusehen, den Hauptast auf die richtige Linie zu setzen (richtet sich nach der Anzahl Nebenäste unterhalb oder oberhalb) und dann sukzessive den Nebenästen eine Linie zuzuteilen.

Auf die früher vorgesehene Verteilung der horizontalen Darstellung auf mehrere Zeilen wird verzichtet.

 

Schritt 3.2: Querverzerrung

Bis jetzt haben wir noch nicht viel erreicht. Die kartografische Darstellung wäre viel direkter zu erreichen gewesen und auch die horizontale Darstellung könnte billiger gemacht werden. Der Grund für die recht aufwendig erstellte Datenstruktur kommt in diesem und im nächsten Schritt zum Vorschein.

Wir wollen nun sowohl in der kartographischen, wie auch in der horizontalen Darstellung die parallelen Gleise durch die Querverzerrung auseinander ziehen.

Der Benutzer gibt uns, zB mit einem Schieber, den Quer-Faktor Q, dieser soll zwischen 1 und 5 variieren. 1 bedeutet keine Verzerrung, 2 bedeutet doppelter Abstand zwischen parallelen Gleisen 5 bedeutet fünffacher Abstand usw. (Nach den bisherigen Erfahrungen reicht eine fünffache Spreizung.)

Für die kartographische Variante ändert sich auf den Polygonen der Äste da, wo der Shift nicht Null ist, gegenüber der unverzerrten Darstellung nichts. Ansonsten gibt es aus Dx und Dy ein Dx* und Dy* durch: Dx* := Dx (Q-1)(x-Shift)  und  Dy* := Dy (Q-1)(y-Shift), die zum Vorgänger zu addieren sind.

Die übrigen Punkte erhalten den Faktor Q für Dx-quer und Dy-quer:

Dx-quer* := Q . Dx-quer  und  Dy-quer* := Q . Dy-quer. Damit ist schon fertig.

Für die horizontale Darstellung ist die Querverzerrung auch keine grosse Sache:

1.   Die Shifts (x-Shift2 + y-Shift2)0.5 werden mit Q multipliziert.

2.   Die y-Richtung der übrigen Punkte (Dx-quer2 + Dy-quer2)0.5  werden mit Q multipliziert.

Die querverzerrte Darstellung verspricht bereits einen gewissen Nutzen, indem ein Bahnhof weniger vergrössert werde muss, um die parallelen Gleise einzeln sehen zu können.

 

Schritt 3.3: Längsschrumpfung

Zu schaffen macht uns noch, dass wir in den Bahnhöfen viel mehr Details auf engem Raum haben verglichen mit der Strecke, ja sogar auf den Ein/Ausfahrten mehr als in der Bahnhofsmitte mit zB 400 m langen Perrons. Daher kommt die Idee, lange Gleiskanten schrumpfen zu lassen.

Leider ergibt sich da eine Komplikation: Wenn die ausgewählte Gleiskante des Skeletts nicht auf die äusserste Weiche eines Bahnhofes trifft, wird ein Teil des Bahnhofes mitgeschrumpft, was zu unerwünschten Effekten führt. Jetzt können wir die Schrumpfabschnitte gebrauchen.

Der Parameter S steht für Schrumpfer. Er kann von 0 (=keine Schrumpfung) bis auf 1 (=maximale Schrumpfung) verstellt werden. Er wird erst wirksam, wenn ein Schrumpfabschnitt eine Länge von über 50 m aufweist, dessen Länge statt mit der realen Länge L nur in einer Länge L›:= 50 + (1-S)(L-50) dargestellt werden soll. Es lässt sich ausrechnen, dass eine Multiplikation von jedem Dx und von jedem Dy von Schrumpfabschnitte länger als 50 m im Body mit dem Faktor F := 1-S + 50S/L  genau diesen Effekt hat.

Mit diesem Faktor werden alle Dx, Dy, Dx-längs und Dy-längs eines Schrumpfabschnittes multipliziert, bevor die Punkte zwecks Positionierung durchgegangen werden, das gilt sowohl für die kartografische wie auch für die horizontale Darstellung.

Bei der Darstellung des Schrumpfers auf dem Schirm sollte man sich keine Nachlässigkeit gestatten: Ein Schieber, der linear von 0 nach 1 geht, würde wohl als unangenehm angesehen, weil die Werte zwischen 0 und 1/2, die kaum je gebraucht werden, schon die Hälfte der Skala ausmachten, währendem der Unterschied zwischen 0,9 und 0,95 vielleicht schwierig einzustellen ist. Ich schlage deshalb einen Teil einer 1/x-Kurve vor, um S einzustellen. Wegen dem asymptotischen Charakter dieser Kurve braucht es ein paar mathematische Manipulationen, um das richtig hinzubekommen:

Wenn x auf dem Schirm linear von 0 auf 1 ansteigt, dann soll S  =  [ 1 – 1/(8x +1) ] . 9/8 sein.  S geht somit ebenfalls von 0 auf 1 aber zuerst schnell und dann immer langsamer. (Angeschrieben werden die S-Werte, nicht die x-Werte.)

Anmerkung: Die Idee hinter dem Schrumpfer ist, dass Bahnhofseinfahrten in der Längsrichtung nahezu geografische Verhältnisse haben, im Vergleich dazu sind Bahnhofgleise (bei entsprechendem S) gekürzt, und Strecken zwischen Bahnhöfen ebenso, Letztere können aber in einer gemässigten Schrumpfung untereinander fast im richtigen Verhältnis gehalten werden, weil der «Sockel» von 50 m keine grosse Rolle mehr spielt, wenn S nicht zu nahe bei 1 liegt. Ob ’50› die richtige Zahl ist, muss man ausprobieren. Eventuell ist auch diese Sockelzahl zu parametrisieren.

 

Schritt 3.4: Zyklen

Wenn keine Zyklen auftauchen, sind wir jetzt im Allgemeinen fertig. Es könnte allerdings sein, dass wir an der Abzweigungsweiche die Quer-Verzerrung verpassen, nämlich dann, wenn die neue Linie direkt an der Weiche in UNO, also am Kernpunkt der Weiche, als Weg über Ablenkung beginnt.

Bei korrekt erstellten Gleispunkten sind allerdings diejenigen, die noch auf der eigentlichen Weiche liegen (in unserer Abstraktion der Anfang bzw. das Ende der Gleiskante) noch der andern Linie zugeteilt, der Linienwechsel erfolgt mitten auf der Gleiskante. Ob das etwas mit dem Bahntrasse zu tun hat, worauf diese Gleispunkte liegen, weiss ich nicht, auf jeden Fall ist es für unsere Zwecke ideal: Die Querverzerrung ergibt auch hier das gewünschte Resultat. Wo das nicht der Fall ist, zB in NEBI, sehe ich keine andere Lösung, als dass der Datenpfleger von UNO die betreffenden Punkte auf die korrekte Liniennummer mutiert.

Bei einem Zyklus geraten wir irgendwann an einen Endpunkt mit Hinweis auf eine bereits dargestellte Ecke. Die Schirmkoordinaten dieser beiden Punkte sind jetzt im Allgemeinen ungleich, bei der horizontalen Darstellung wegen der Schematisierung, bei der kartografischen nur wegen der Verzerrung. Während die Schematisierung der horizontalen Darstellung wohl vorgeht, wird man das da so stehen lassen, aber bei der kartografischen Darstellungen empfindet der Benutzer das bestimmt als unschön. Eine Behebung, die die meisten Fälle befriedigend erledigt, ist hier vom Aufwand her vertretbar.

Dem hierarchisch tieferen Ast werden die Dx und Dy entlang seiner Kette so gekürzt oder vergrössert, dass sein Endpunkt auf die bereits dargestellte Ecke zu liegen kommt. (Es werden alle Dx und Dy herangezogen, auch diejenige von Gleiskanten nicht grösser als 50 m.) Das passiert gleichmässig über den ganzen Ast. Das könnte Rundungsprobleme geben, die sich ungünstig summieren, das wird man sehen.

Konkret: Sei (Ux, Uy) die Koordinaten des Ursprungs des betroffenen Astes, (Vx, Vy) diejenigen des mit der Ecke mit den Koordinaten (Ex, Ey) zu vereinigenden Endpunktes. Die Korrektur ist möglichst gleichmässig zu verteilen. Deshalb ist zuerst die Gesamtlänge  – nicht der Luftlinie! –  des betroffenen Astes zu bestimmen, also die Summe aller Abstände zwischen den Ecken, wenn Li  die Länge der i-ten Ecke zu ihrem Vorgänger ist, so sei:

L := S Li . Daraus folgt für das Additiv (ai, bi) von (Dx, Dy) der i-ten Ecke :

ai = (Vx – Ex) Li / L  und  bi = (Vy – Ey) Li / L

Theoretisch sind unschwer Fälle denkbar, die zu einem ganz unbefriedigendem Resultat führen: Wenn der grösste Teil des Zyklus aus höheren Ästen besteht und nur noch ein kurzer Ast zum Ausgleich herangezogen wird. Ob das in Praxis auch vorkommt, wird man sehen. Im Falle eines Falles dürfte es genügen, die Hierarchie der Äste anders festzulegen.

 

 


TEIL 4: MANUELLE EINGRIFFE

 

Schritt 4.1: Verbesserung der Darstellung

Wie erwähnt, sind die Linienzuteilungen mitunter inkonsequent und manchmal aus andern Gründen für den Zweck der Darstellung ungeeignet. Mit den zwei hier vorgeschlagenen Handmanipulationen wären diese Schwächen mit vertretbarem Aufwand zu beheben.

Auch die Querverzerrung kann zu unerwünschten Effekten führen. Aus der bisherigen Erfahrung resultieren drei Vorschläge, wobei es sich bei jedem fragt, ob es sich wirklich lohnt, das ist letztlich ein Ermessen.

4.1.1:   Verschiebung des Linienwechsels auf einer Gleiskante

Klassischer Fall sind Abzweigungen, bei denen die Gleise noch eine Weile parallel auf demselben Gleiskörper verlaufen, um dann (ohne Weiche) auseinander zu gehen. Nicht immer ist der Linienwechsel erst dort, wo der gemeinsame Gleiskörper aufgegeben wird.

4.1.2:   Zuteilung eines Gebietes zu einer andern Linie

Mit einem Polygonzug kann ein Gebiet, zB eine Abstellgruppe, eingegrenzt und einer andern Linie zugeteilt werden. Als ‘andere Linie‘ möglich ist sowohl eine bestehende als auch eine artifizielle, die nur für diese Darstellung existiert.

Nötig ist das, wenn Gleisfelder schräg zum Hauptstrang angelegt sind wie in Luzern oder wenn im selben Hauptstrang verschiedene Linie verlaufen wie in Zürich Vorbahnhof.

Häufig wird man nach diesem Befehl noch die Verschiebung des Linienwechsels auf einer Gleiskante verwenden müssen, um das Gewünschte zu erhalten.

4.1.3:   Verschiebung eines Seitenastes

Bei der Querverzerrung können sich Gleise von verschiedenen Ästen in die Quere kommen. Man möchte deshalb den Offset des eines Astes verschieben. Das geht aber nicht, weil der Offset noch auf dem ranghöheren Ast sitzt.

Bei der horizontalen Darstellung reicht es, wenn der Benutzer die Linie des betroffenen Astes auf dem Schirm verschieben kann. Bei der kartografischen wird er eine Loslösung des Astes vom Offset auf dem höheren Ast vornehmen müssen (vorschlagsweise dargestellt durch eine gepunktete Linie zwischen den beiden Offsets).

4.1.4:   Korrektur der Querverzerrung

Es kommt immer wieder vor, dass die Querverzerrung in gewissen Teilen zu stark wirkt, wenn zB ein paar Gleise um ein Gebäude herum laufen, das dann in gleichem Mass ‘‘dicker‘‘ wird, wie die Gleise auseinander gezogen werden.

Da müsste man für einen BP, den man auswählen könnte, die Querverzerrung manipulieren resp. differenzieren können. Ich stelle mir vor, dass der Computer ein Band anzeigt, das mittels Punkten, zB jeden Meter, die Querverzerrung anzeigt. Diese Punkte lassen sich dann manuell verschieben, was eine entsprechende ungleichmässige Verteilung der Querverzerrung nach sich ziehen soll (bis hin sie gesamthaft an diesem BP geringer zu halten).

Es ist auch denkbar, dass man nicht BPs auswählt sondern analog 4.1.2 mit einem Polygonzug das Gebiet definiert.

(Nicht ganz ausgeschlossen ist eine automatisierte Version dieser Funktion: Wo die Punkte selten sind, wird weniger verzerrt. Mir scheint das aber doch problematisch und recht aufwendig zu sein, weshalb ich das nicht vorschlage.)

4.1.5:   Virtuelle Gleiskante als Skelettgleiskante

Es wurde festgestellt, dass eine Folge von Gleiskante als Ausgangspunkt der ganzen Darstellung dann unproblematisch ist, wenn entweder nur wenige räumlich nahe Gleise vorhanden sind, so wie das meistens auf der Strecke der Fall ist, oder die Gleiskanten sind gerade oder parallel zu den andern Gleiskanten gebogen mit nicht zu engen Radien, wie das auf Bahnhöfen üblich ist. Im Gleiskomplex zwischen Zürich und Zürich-Altstetten haben aber alle Duchfahrgleise, die sich als Skelettkanten ansonsten gut eignen würden eine S-förmige Kurve, die die andern Gleise zum grössten Teil nicht mitmachen.

Da wäre es von Vorteil, als Ausgangslinie nicht eine Gleiskantenfolge sondern eine Gerade zu nehmen, die zB mit einem Prellbock und einer Weiche in Altstetten definiert werden könnte.

 

Schritt 4.2: Umwandlung der horizontalen Darstellung in einen «abstrakten Plan»

Es hat sich gezeigt, dass der Aufwand, um aus einer horizontalen Darstellung eine abstrakte zu formen, nicht eben gross, wenn dazu nur drei Funktionen und ein horizontales Gitter zur Verfügung stehen. (Natürlich ist die horizontale Darstellung als Ausgangspunkt dazu weit geeigneter als eine kartografische.)

Die folgenden Funktionen nur für die horizontale Darstellung gedacht.

4.2.1:   Eliminierung von Punkten

Um gerade Linien zu erhalten genügt es, die von DfA alle 10 Meter gelieferten Punkte zu eliminieren. Weichen und andere Gleiskantenenden sind dabei tabu.

Wir können mit dieser Funktion eine Kante anwählen, indem wir einen der Gleispunkte darauf anwählen. Nach eventuell weiteren Auswahlen von Punkten ermöglicht ein weiterer Befehl die Eliminierung sämtlicher anderen Punkte der Gleiskante.

4.2.2:   Restore einer Kante

Vielleicht hat der Benutzer etwas zu viele Punkte weggewählt. Dazu gibt es ein Restore: Die gewählte Kante erhält alle Punkte zurück. Auch Verschiebungen (siehe nächster Punkt) sind weg, nicht aber Verschiebungen der Gleisendpunkte.

4.2.3:   Verschiebung von Punkten

Um nicht nur gerade Linien sondern auch (vorwiegend) waagrechte Linien zu haben, muss man die Punkte verschieben können. Das soll man ausgewählte Punkte aber auch mit Weichen und übrigen Gleisenden in alle Richtungen tun können.

Wichtig dabei ist, dass die Verschiebungen in die Ursprungsstruktur zurück gerechnet werden. So funktionieren Querverzerrung und Längsschrumpfung auch nach Verschiebungen immer noch so, wie es der Benutzer erwartet.

4.2.4:   Horizontalgitter

Um nicht allzu feinfühlig-langwierig mit der Maus zirkeln zu müssen (um wirklich waagrechte Linien hinzukriegen), ist es sinnvoll ein Gitter zu haben, auf jeden Fall in der y-Richtung des Bildschirmes. (In der x-Richtung ist das eher überflüssig.)

Das Gitter soll so installiert werden, dass es auf der Ursprungsstruktur konstant ist. Durch Zoomen oder Verstellung der Querverzerrung bekommt der Benutzer also nicht ein anderes Gitter. Dass so das Gitter mit Querverzerrung und Zoom etwas grob werden kann, nehmen wir in Kauf.

Selbstverständlich sollen die Gleiskanten des Skeletts auf den Gitterlinien liegen.

4.2.5:   Abspeichern und Laden des Gespeicherten

Bearbeitet man ein Bild von Hand, so will man die Arbeit bewahren können und am nächsten Tag wieder zur Verfügung haben. Dazu dient diese Funktion. Ist beim nächsten Laden eine neue Gleiskante da, so ist diese natürlich ‘‘uneditiert‘‘, aber nur diese. Umgekehrt ist eine gelöschte Gleiskante natürlich mitsamt der Bearbeitung weg. Das sollte ohne weiteres möglich sein.

 

NACHTRAG: Zoom-Problem: Umrechnung auf den Schirm

Die Umrechnung der kumulierten Meter in x – und in y-Richtung in Metern auf Schirmkoordinaten ist an sich nur Standard, eine kleine Komplikation verursachen die Verzerrungen beim Zoom.

Die Datenhaltung in der Struktur des Skeletts erlaubt es mittels Durchlaufen aller Punkte, zwar nicht sofort, aber einigermassen schnell zu den Extremwerten  – grösstes und kleinstes x und y –  zu kommen, die dann für das Anfangsbild so auf Schirmkoordinaten umgerechnet werden, dass in einer Dimension die Grösse des Schirms ausgenützt wird, womit der Massstab im kartografischen Sinn gegeben wäre. Die Verwendung eines Zooms mit Auswahl eines Rechteckes auf dem Schirm ist dann ebenfalls nur Standard.

Was aber, wenn im gezoomten Zustand die Parameter verstellt werden? Es wäre wohl nicht beliebt, das wieder als Anfangsbild zu verstehen. Die veränderten Parameter verändern aber notwendigerweise, was auf dem Schirm sichtbar ist und was nicht. Ich sehe 2 vernünftige Verfahren in diesem Fall:

  1. Virtueller Schirm: Der virtuelle Schirm hat stets die Grösse, die das ganze Bild beanspruchen würde. Beim Anfangsbild deckt sich dieser mit dem realen Schirm. Jedes Zoomen verändert ihn. Ein durch Parameterveränderung geändertes Bild wird in den virtuellen Schirm eingepasst, auf dem der Zoom dann in unveränderter Relation stehen soll. (Lösung des Prototypen, wobei der virtuelle Schirm etwa die zehnfache Grösse des realen Schirmes hat und immer auf den vollen Schirm projiziert wird.)
  2. Konstanter Massstab: Wenn der kartographische Massstab festlegt, dass 100 Meter n Pixel auf dem Schirm entsprechen, der Zoom das auf a.n verschoben hat, dann bleibt das so auch bei der einer Veränderung der Parameter Q und S.

 

25.05.2021