Zum Inhalt

zielgraph

Modul Zielgraph

Ein Zielgraph stellt die Fahrpläne von Zügen in einem NetworkX-Graph dar. Die Knoten des Graphen sind die Fahrziele (Fahrplaneinträge) aller Züge. Zu einem Zug gehörende Knoten werden in der Fahrplanreihenfolge durch Kanten verbunden. Ausserdem können durch Flags entstehende Züge mit dem Stammzug verbunden werden.

Classes:

ZielGraph

ZielGraph(incoming_graph_data=None, **attr)

              flowchart TD
              stskit.model.zielgraph.ZielGraph[ZielGraph]

              

              click stskit.model.zielgraph.ZielGraph href "" "stskit.model.zielgraph.ZielGraph"
            

Fahrplan in Graphform.

Der Zielgraph enthält den Fahrplan aller Züge. Die Punkte sind gemäss Anordnung im Fahrplan sowie planmässigen (Ersatz, Kuppeln, Flügeln) und dispositiven Abhängigkeiten (Kreuzung, Ueberholen, Abwarten, Betriebshalt, etc.) verbunden.

Der Zielgraph ist gerichtet.

Methods:

Source code in stskit/model/zielgraph.py
def __init__(self, incoming_graph_data=None, **attr):
    super().__init__(incoming_graph_data, **attr)
    self.zuganfaenge: dict[int, ZielLabelType] = {}
    self.zugenden: dict[int, ZielLabelType] = {}
    self._pendente_verbindungen: set[tuple[ZielLabelType, int, str]] = set()

einfahrtszeiten_korrigieren

einfahrtszeiten_korrigieren(lg: LinienGraph, bg: BahnhofGraph, metrik: str = 'fahrzeit_schnitt') -> None

Ein- und Ausfahrtszeiten korrigieren.

Korrigiert die Ein- und Ausfahrzeiten aller im Zielgraph verzeichneten Züge. Da der Simulator keine Ein- und Ausfahrtszeiten angibt, werden die Ein- und Ausfahrzeiten anhand der Fahrzeitangaben im Liniengraph korrigiert.

Die Fahrzeit wird für jede Ein- und Ausfahrt nach dem ersten vorandenen Wert in folgender Liste bestimmt:

  1. fahrzeit_manuell-Attribut im Liniengraph
  2. Von metrik benanntes Attribut im Liniengraph.
  3. Defaultwert 1 Minute, auch bei Lookup-Fehlern.

Da die Fahrzeiten im Liniengraph zur Laufzeit eines Spiels gemessen werden, können sie am Anfang fehlen.

Parameters:

  • lg

    (LinienGraph) –

    Der Liniengraph enthält die Fahrzeiten zwischen den Bahnhofteilen. Wird die Verbindung nicht gefunden, wird die Fahrzeit auf 1 Minute geschätzt.

  • bg

    (BahnhofGraph) –

    Der Bahnhofgraph enthält die Zuordnung von Gleisen zu Bahnhofteilen.

  • metrik

    (str, default: 'fahrzeit_schnitt' ) –

    Name des LinienGraph-Attributs, das die Fahrzeit angibt (normalerweise eines von: fahrzeit_schnitt, fahrzeit_min, fahrzeit_max).

Source code in stskit/model/zielgraph.py
def einfahrtszeiten_korrigieren(self,
                                lg: LinienGraph,
                                bg: BahnhofGraph,
                                metrik: str = "fahrzeit_schnitt",
                                ) -> None:
    """
    Ein- und Ausfahrtszeiten korrigieren.

    Korrigiert die Ein- und Ausfahrzeiten aller im Zielgraph verzeichneten Züge.
    Da der Simulator keine Ein- und Ausfahrtszeiten angibt,
    werden die Ein- und Ausfahrzeiten anhand der Fahrzeitangaben im Liniengraph korrigiert.

    Die Fahrzeit wird für jede Ein- und Ausfahrt nach dem ersten vorandenen Wert in folgender Liste bestimmt:

    1. `fahrzeit_manuell`-Attribut im Liniengraph
    2. Von metrik benanntes Attribut im Liniengraph.
    3. Defaultwert 1 Minute, auch bei Lookup-Fehlern.

    Da die Fahrzeiten im Liniengraph zur Laufzeit eines Spiels gemessen werden, können sie am Anfang fehlen.

    Args:
        lg: Der Liniengraph enthält die Fahrzeiten zwischen den Bahnhofteilen.
            Wird die Verbindung nicht gefunden, wird die Fahrzeit auf 1 Minute geschätzt.
        bg: Der Bahnhofgraph enthält die Zuordnung von Gleisen zu Bahnhofteilen.
        metrik: Name des LinienGraph-Attributs, das die Fahrzeit angibt
            (normalerweise eines von: `fahrzeit_schnitt`, `fahrzeit_min`, `fahrzeit_max`).
    """

    for fid1, fid2 in self.edges(data=False):
        ziel1_data: ZielGraphNode = self.nodes[fid1]
        ziel2_data: ZielGraphNode = self.nodes[fid2]
        if ziel1_data.typ == 'E' or ziel2_data.typ == 'A':
            try:
                bst1 = bg.find_superior(ziel1_data.plan_bst, {'Anst', 'Bf'})
            except KeyError:
                bst1 = None
            try:
                bst2 = bg.find_superior(ziel2_data.plan_bst, {'Anst', 'Bf'})
            except KeyError:
                bst2 = None

            try:
                data: LinienGraphEdge = lg.edges[(bst1, bst2)]
                if TYPE_CHECKING:
                    assert isinstance(data, LinienGraphEdge)
                fahrzeit = max(1, data.get("fahrzeit_manuell", 0) or data.get(metrik, 0))
            except KeyError:
                logger.warning(f"Verbindung {bst1}-{bst2} nicht im Liniengraph.")
                fahrzeit = 1

            if ziel1_data.typ == 'E':
                try:
                    dt = datetime.datetime.combine(datetime.datetime.today(), minutes_to_time(ziel2_data.p_an))
                except AttributeError:
                    continue
                else:
                    dt -= datetime.timedelta(minutes=fahrzeit)
                    einfahrtszeit = dt.time()
                    ziel1_data.update(p_an=time_to_minutes(einfahrtszeit),
                                      p_ab=time_to_minutes(einfahrtszeit))

            elif ziel2_data.typ == 'A':
                try:
                    dt = datetime.datetime.combine(datetime.datetime.today(), minutes_to_time(ziel1_data.p_ab))
                except AttributeError:
                    continue
                else:
                    dt += datetime.timedelta(minutes=fahrzeit)
                    ausfahrtszeit = dt.time()
                    ziel2_data.update(p_an=time_to_minutes(ausfahrtszeit),
                                      p_ab=time_to_minutes(ausfahrtszeit))

next_node

Nächster Zielknoten eines Zuges

Parameters:

  • node

    (ZielLabelType) –

    Label des Ursprungknotens

  • ersatz_erlaubt

    (bool, default: False ) –

    Neuen Zug nach Ersatz- oder Kuppelflags verfolgen.

Raises:

  • ValueError

    Keinen passenden Knoten gefunden.

Source code in stskit/model/zielgraph.py
def next_node(self, node: ZielLabelType, ersatz_erlaubt: bool = False) -> ZielLabelType:
    """
    Nächster Zielknoten eines Zuges

    Args:
        node: Label des Ursprungknotens
        ersatz_erlaubt: Neuen Zug nach Ersatz- oder Kuppelflags verfolgen.

    Raises:
        ValueError: Keinen passenden Knoten gefunden.
    """

    zid = node.zid
    for n in self.successors(node):
        if n.zid == zid:
            return n
        elif ersatz_erlaubt:
            if self.edges[(node, n)]['typ'] in {'E', 'K'}:
                return n

    raise ValueError(f"Kein nächster Node zu {node}")

prev_node

Vorheriger Zielknoten eines Zuges

Parameters:

  • node

    (ZielLabelType) –

    Label des Ursprungknotens

  • ersatz_erlaubt

    (bool, default: False ) –

    Stammzug vor Ersatz- oder Flügelflags verfolgen.

Raises:

  • ValueError

    Keinen passenden Knoten gefunden.

Source code in stskit/model/zielgraph.py
def prev_node(self, node: ZielLabelType, ersatz_erlaubt: bool = False) -> ZielLabelType:
    """
    Vorheriger Zielknoten eines Zuges

    Args:
        node: Label des Ursprungknotens
        ersatz_erlaubt: Stammzug vor Ersatz- oder Flügelflags verfolgen.

    Raises:
        ValueError: Keinen passenden Knoten gefunden.
    """

    zid = node.zid
    for n in self.predecessors(node):
        if n.zid == zid:
            return n
        elif ersatz_erlaubt:
            if self.edges[(n, node)]['typ'] in {'E', 'F'}:
                return n

    raise ValueError(f"Kein vorheriger Node zu {node}")

verspaetung_von_zug

verspaetung_von_zug(zug: ZugDetails)

Verspätungsfelder von ZugDetails übernehmen.

Die Verspätungsfelder werden anhand der ZugDetails aktualisiert. Die Statusfelder müssen bereits korrekt gesetzt sein. Es werden nur die noch nicht abgefahrenen Ziele aktualisiert.

Source code in stskit/model/zielgraph.py
def verspaetung_von_zug(self, zug: ZugDetails):
    """
    Verspätungsfelder von ZugDetails übernehmen.

    Die Verspätungsfelder werden anhand der ZugDetails aktualisiert.
    Die Statusfelder müssen bereits korrekt gesetzt sein.
    Es werden nur die noch nicht abgefahrenen Ziele aktualisiert.
    """

    for fid in self.zugpfad(zug.zid):
        data = self.nodes[fid]
        if data.status == '':
            data.v_an = zug.verspaetung
            data.v_ab = zug.verspaetung
        elif data.status == 'an':
            data.v_ab = zug.verspaetung

ziel_status_von_zug

ziel_status_von_zug(zug: ZugDetails)

Zielstatusfelder aus ZugDetails übernehmen.

Die Zielstatusfelder werden anhand der ZugDetails aktualisiert. Von ZugDetails benötigt werden: fahrplan[].fid, ziel_index, amgleis

Abgefahrene Zielknoten werden mit 'ab' markiert, die noch nicht abgefahrenen mit ''. Wenn der Zug an einem Ziel steht, ist der Status 'an'.

Source code in stskit/model/zielgraph.py
def ziel_status_von_zug(self, zug: ZugDetails):
    """
    Zielstatusfelder aus ZugDetails übernehmen.

    Die Zielstatusfelder werden anhand der ZugDetails aktualisiert.
    Von ZugDetails benötigt werden: fahrplan[].fid, ziel_index, amgleis

    Abgefahrene Zielknoten werden mit 'ab' markiert, die noch nicht abgefahrenen mit ''.
    Wenn der Zug an einem Ziel steht, ist der Status 'an'.
    """

    status = 'ab' if zug.sichtbar else ''
    try:
        fid_aktuell = ZielLabelType.from_fahrplanzeile(zug.fahrplan[zug.ziel_index].fid)
    except (IndexError, KeyError, TypeError):
        # kein ziel oder kein fahrplan
        fid_aktuell = None
        if len(zug.fahrplan):
            # noch nicht eingefahren
            status = ''
        else:
            # ausgefahren
            status = 'ab'

    for fid in self.zugpfad(zug.zid):
        data = self.nodes[fid]
        if data.fid == fid_aktuell:
            status = 'an' if zug.amgleis else ''
        elif status == 'an':
            status = ''
        data.status = status

zug_details_importieren

zug_details_importieren(zug: ZugDetails, einfahrt: Knoten | None = None, ausfahrt: Knoten | None = None, params: PlanungParams | None = None) -> set[tuple[str, int, int]]

Ziel- und Zuggraphen nach Fahrplan eines Zuges aktualisieren.

Die Graphen werden in der Dokumentation der Klasse beschrieben.

Diese Methode fügt neue Knoten und ihre Kanten zum Graphen hinzu oder aktualisiert bestehende. Es werden keine Knoten und Kanten gelöscht.

Notes
  • Der vom Simulator gemeldete Fahrplan enthält nur anzufahrende Ziele. Im Zielgraphen werden die abgefahrenen Ziele jedoch beibehalten.
  • Die Methode fügt auch Knoten und Kanten für Einfahrten und Ausfahrten ein, wenn diese in den von- und nach-Feldern angegeben sind. Einfahrten werden nur eingefügt, wenn der Zug noch nicht eingefahren ist.

Parameters:

  • zug

    (ZugDetails) –

    ZugDetails-Objekt vom Simulator.

  • einfahrt

    (Knoten | None, default: None ) –

    Einfahrtsknoten, falls im von-Feld angegeben.

  • ausfahrt

    (Knoten | None, default: None ) –

    Ausfahrtssknoten, falls im nach-Feld angegeben.

  • params

    (PlanungParams | None, default: None ) –

    Parametrisierung der Mindestaufenthaltsdauer nach Zieltyp. Wenn None, werden die Defaultwerte der PlanungParams-Klasse verwendet.

Returns:

  • set[tuple[str, int, int]]

    Abgehende Verknüpfungen des Zuges mit anderen Zügen.

  • set[tuple[str, int, int]]

    Tupel von Typ ('E', 'K', 'F'), zid des Stammzuges, zid des Folgezuges.

Source code in stskit/model/zielgraph.py
def zug_details_importieren(self,
                            zug: ZugDetails,
                            einfahrt: Knoten | None = None,
                            ausfahrt: Knoten | None = None,
                            params: PlanungParams | None = None,
                            ) -> set[tuple[str, int, int]]:
    """
    Ziel- und Zuggraphen nach Fahrplan eines Zuges aktualisieren.

    Die Graphen werden in der Dokumentation der Klasse beschrieben.

    Diese Methode fügt neue Knoten und ihre Kanten zum Graphen hinzu oder aktualisiert bestehende.
    Es werden keine Knoten und Kanten gelöscht.

    Notes:
        - Der vom Simulator gemeldete Fahrplan enthält nur anzufahrende Ziele.
            Im Zielgraphen werden die abgefahrenen Ziele jedoch beibehalten.
        - Die Methode fügt auch Knoten und Kanten für Einfahrten und Ausfahrten ein,
            wenn diese in den von- und nach-Feldern angegeben sind.
            Einfahrten werden nur eingefügt, wenn der Zug noch nicht eingefahren ist.

    Args:
        zug: ZugDetails-Objekt vom Simulator.
        einfahrt: Einfahrtsknoten, falls im von-Feld angegeben.
        ausfahrt: Ausfahrtssknoten, falls im nach-Feld angegeben.
        params: Parametrisierung der Mindestaufenthaltsdauer nach Zieltyp.
            Wenn None, werden die Defaultwerte der PlanungParams-Klasse verwendet.

    Returns:
        Abgehende Verknüpfungen des Zuges mit anderen Zügen.
        Tupel von Typ ('E', 'K', 'F'), zid des Stammzuges, zid des Folgezuges.
    """

    if params is None:
        params = PlanungParams()

    ziel1: FahrplanZeile | None = None
    fid1: ZielLabelType | None = None
    anfang: ZielLabelType | None = None
    ende: ZielLabelType | None = None
    zug2: ZugDetails = zug
    zid2: int = zug2.zid
    links: set[tuple[str, int, int]] = set()

    for ziel2 in zug2.fahrplan:
        fid2 = ZielLabelType.from_fahrplanzeile(ziel2.fid)
        if anfang is None:
            anfang = fid2
        ende = fid2

        ziel_data = ZielGraphNode.from_fahrplanzeile(ziel2)
        ziel_data.mindestaufenthalt_setzen(params)
        self.add_node(fid2, **ziel_data)

        if ziel1:
            if fid1 != fid2 and not self.has_edge(fid1, fid2):
                self.add_edge(fid1, fid2, typ='P')

        if zid3 := ziel2.ersatz_zid():
            self._ziele_verbinden(fid2, zid3, 'E')
            links.add(('E', zid2, zid3))

        if zid3 := ziel2.kuppel_zid():
            self._ziele_verbinden(fid2, zid3, 'K')
            links.add(('K', zid2, zid3))

        if zid3 := ziel2.fluegel_zid():
            self._ziele_verbinden(fid2, zid3, 'F')
            links.add(('F', zid2, zid3))

        ziel1 = ziel2
        fid1 = fid2

    if not zug2.sichtbar and einfahrt is not None:
        fz2 = zug2.fahrplan[0]
        fid2 = ZielLabelType.from_fahrplanzeile(fz2.fid)
        einfahrtszeit = time_to_minutes(fz2.an or fz2.ab)

        try:
            fid1 = ZielLabelType(zid2, MIN_MINUTES, einfahrt.enr)
            ziel_data = ZielGraphNode(
                obj=None,
                fid=fid1,
                zid=zid2,
                typ='E',
                plan=einfahrt.name,
                gleis=einfahrt.name,
                flags='',
                lokumlauf=False,
                lokwechsel=None,
                status='',
                p_an=einfahrtszeit,
                p_ab=einfahrtszeit,
                mindestaufenthalt=0
            )
        except (AttributeError, KeyError, TypeError):
            logger.error(f"Fehler in Einfahrtsdaten {fid1}, Knoten {einfahrt}")
        else:
            self.add_node(fid1, **ziel_data)
            anfang = fid1
            if ende is None:
                ende = fid1
            if not self.has_edge(fid1, fid2):
                self.add_edge(fid1, fid2, typ='P')

    if zug2.nach and ausfahrt is not None:
        fz2 = zug2.fahrplan[-1]
        fid2 = ZielLabelType.from_fahrplanzeile(fz2.fid)
        ausfahrtszeit = time_to_minutes(fz2.ab or fz2.an)

        try:
            fid1 = ZielLabelType(zid2, MAX_MINUTES, ausfahrt.enr)
            ziel_data = ZielGraphNode(
                obj=None,
                fid=fid1,
                zid=zid2,
                typ='A',
                plan=ausfahrt.name,
                gleis=ausfahrt.name,
                flags='',
                lokumlauf=False,
                lokwechsel=None,
                status='',
                p_an=ausfahrtszeit,
                p_ab=ausfahrtszeit,
                mindestaufenthalt=0
            )
        except (AttributeError, KeyError):
            logger.warning(f"Fehler in Ausfahrtsdaten {fid1}, Knoten {ausfahrt}")
        else:
            self.add_node(fid1, **ziel_data)
            if anfang is None:
                anfang = fid1
            ende = fid1
            if not self.has_edge(fid2, fid1):
                self.add_edge(fid2, fid1, typ='P')

    if zid2 not in self.zuganfaenge:
        if anfang is not None:
            self.zuganfaenge[zid2] = anfang
        if ende is not None:
            self.zugenden[zid2] = ende
    self.ziel_status_von_zug(zug2)
    self.verspaetung_von_zug(zug2)
    self._verbindungen_herstellen(zid2)

    return links

zugpfad

zugpfad(zid: int) -> Generator[ZielLabelType, None, None]

Generator für die Knoten eines Zuges

Beginnend mit dem Startknoten liefert der Generator die Knoten-IDs eines Zuges in der Reihenfolge ihres Auftretens.

Source code in stskit/model/zielgraph.py
def zugpfad(self, zid: int) -> Generator[ZielLabelType, None, None]:
    """
    Generator für die Knoten eines Zuges

    Beginnend mit dem Startknoten liefert der Generator die Knoten-IDs eines Zuges
    in der Reihenfolge ihres Auftretens.
    """

    node = self.zuganfaenge[zid]
    while node is not None:
        yield node

        for n in self.successors(node):
            if n.zid == zid:
                node = n
                break
        else:
            node = None

ZielGraphEdge


              flowchart TD
              stskit.model.zielgraph.ZielGraphEdge[ZielGraphEdge]

              

              click stskit.model.zielgraph.ZielGraphEdge href "" "stskit.model.zielgraph.ZielGraphEdge"
            

Attribute einer ZielGraph-Kante

Attributes:

  • typ

    Verbindungstyp:

    Wert Bedeutung
    P planmässige Fahrt
    E Ersatzzug
    F Flügelung
    K Kupplung
    R vom Fdl angeordnete Rangierfahrt, z.B. bei Lokwechsel
    A vom Fdl angeordnete Abhängigkeit
    O Hilfskante für Sortierordnung
  • v

    Verspätung auf dieser Verbindung in Minuten. Wird in der Prognose verwendet, ist daher nicht persistent.

ZielGraphNode


              flowchart TD
              stskit.model.zielgraph.ZielGraphNode[ZielGraphNode]

              

              click stskit.model.zielgraph.ZielGraphNode href "" "stskit.model.zielgraph.ZielGraphNode"
            

Attribute eines ZielGraph-Knotens.

Attributes:

  • obj

    stsobj.FahrplanZeile-Objekt (fehlt bei Ein- und Ausfahrten).

  • fid

    Fahrplanziel-ID bestehend aus Zug-ID, Ankunfts- oder Abfahrtszeit in Minuten, Plangleis. Siehe stsobj.FahrplanZeile.fid. Bei Ein- und Ausfahrten wird statt dem Gleiseintrag die Elementnummer (enr) eingesetzt, und die Zeitkomponente ist MIN_MINUTES (Einfahrt) oder MAX_MINUTES (Ausfahrt).

  • zid

    Zug-ID

  • typ

    Zielpunkttyp:

    Wert Bedeutung
    H Planmässiger Halt
    D Durchfahrt
    E Einfahrt
    A Ausfahrt
    B Betriebshalt (vom Sim nicht verwendet)
    S Signalhalt (vom Sim nicht verwendet)
  • plan

    Gleis- oder Anschlussname nach Fahrplan.

  • gleis

    Gleis- oder Anschlussname nach aktueller Disposition.

  • p_an

    Planmässige Ankunftszeit in Minuten. Bei Ein- und Ausfahrten wird die Ankunfts- und Abfahrtszeit geschätzt.

  • p_ab

    Planmässige Abfahrtszeit in Minuten. Bei Ein- und Ausfahrten wird die Ankunfts- und Abfahrtszeit geschätzt.

  • flags

    Originalflags

  • lokwechsel

    Lokwechselflag mit Nummern der Ein- und Ausfahrtsgleisen der Ersatzlok/Abstelllok.

  • lokumlauf

    Lokumlaufflag.

  • mindestaufenthalt

    Minimale Aufenthaltsdauer in Minuten. Schätzung, wie lange sich der Zug mindestens an diesem Ziel aufhält, auch wenn er laut Fahrplan früher abfahren müsste.

    Die Mindestaufenthaltsdauer wird von der Simulatorschnittstelle nicht angegeben und muss von uns geschätzt werden, z.B. mittels konfigurierten Parametern durch mindestaufenthalt_setzen.

  • status

    Status des Ziels. Bestimmt, ob die Ankunfts- und/oder Abfahrtszeit definitiv ist.

    Wert Bedeutung
    '' Ziel noch nicht erreicht
    an am Ziel angekommen
    ab vom Ziel abgefahren
  • v_an

    Ankunftsverspätung in Minuten

  • v_ab

    Abfahrtsverspätung in Minuten

Methods:

e_ab property

e_ab: int | float

Erwartete Abfahrtszeit in Minuten

AttributeError, wenn keine Abfahrtszeit gespeichert ist. Wenn keine Verspätung gespeichert ist, wird 0 angenommen.

e_an property

e_an: int | float

Erwartete Ankunftszeit in Minuten

AttributeError, wenn keine Ankunftszeit gespeichert ist. Wenn keine Verspätung gespeichert ist, wird 0 angenommen.

enr property

enr: int | None

Elementnummer des Anschlussgleises bei Ein- oder Ausfahrt.

None, wenn das Ziel ein normales Gleis ist.

gleis_bst property

gleis_bst: BahnhofElement

Effektives Gleis in Betriebsstellen-Notation.

plan_bst property

plan_bst: BahnhofElement

Plangleis in Betriebsstellen-Notation.

from_fahrplanzeile classmethod

from_fahrplanzeile(fahrplanzeile: FahrplanZeile) -> ZielGraphNode

Daten aus Fahrplanzeile übernehmen.

Die folgenden Properties werden direkt übernommen: obj, fid, zid, plan, gleis, typ, flags, p_an, p_ab. mindestaufenthalt wird auf 0 gesetzt. Alle anderen müssen separat gesetzt werden.

Parameters:

  • fahrplanzeile

    (FahrplanZeile) –

    Fahrplanzeile-Objekt von der Simulatorschnittstelle.

Source code in stskit/model/zielgraph.py
@classmethod
def from_fahrplanzeile(cls: type, fahrplanzeile: FahrplanZeile) -> ZielGraphNode:
    """
    Daten aus Fahrplanzeile übernehmen.

    Die folgenden Properties werden direkt übernommen:
    obj, fid, zid, plan, gleis, typ, flags, p_an, p_ab.
    mindestaufenthalt wird auf 0 gesetzt.
    Alle anderen müssen separat gesetzt werden.

    Args:
        fahrplanzeile: Fahrplanzeile-Objekt von der Simulatorschnittstelle.
    """

    d = cls(
        obj=fahrplanzeile,
        fid=ZielLabelType.from_fahrplanzeile(fahrplanzeile.fid),
        zid=fahrplanzeile.zug.zid,
        plan=fahrplanzeile.plan,
        gleis=fahrplanzeile.gleis,
        typ='D' if fahrplanzeile.durchfahrt() else 'H',
        flags=fahrplanzeile.flags,
        lokumlauf=fahrplanzeile.lokumlauf(),
        lokwechsel=fahrplanzeile.lokwechsel(),
        status='',
        mindestaufenthalt=0
    )

    if fahrplanzeile.an is not None:
        d['p_an'] = time_to_minutes(fahrplanzeile.an)
    if fahrplanzeile.ab is not None:
        d['p_ab'] = time_to_minutes(fahrplanzeile.ab)

    return d

mindestaufenthalt_setzen

mindestaufenthalt_setzen(params: PlanungParams | None = None)

Mindestaufenthalt-Property auf Vorgabewert setzen.

Der Mindestaufenthalt wird gemäss übergebenen Parametern aus dem Zieltyp und den Flags berechnet. Er setzt sich zusammen aus einer Basiskomponente nach Planhalt, Ersatz, Kupplung oder Flügelung, und einer additiven Komponente bei Richtungswechsel, Lokwechsel oder Lokumlauf.

Parameters:

  • params

    (PlanungParams | None, default: None ) –

    Aufenthaltsparameter aus Konfiguration. Wenn das Argument fehlt, werden die Defaultwerte der PlanungParams-Klasse verwendet.

Source code in stskit/model/zielgraph.py
def mindestaufenthalt_setzen(self, params: PlanungParams | None = None):
    """
    Mindestaufenthalt-Property auf Vorgabewert setzen.

    Der Mindestaufenthalt wird gemäss übergebenen Parametern aus dem Zieltyp und den Flags berechnet.
    Er setzt sich zusammen aus einer Basiskomponente nach Planhalt, Ersatz, Kupplung oder Flügelung,
    und einer additiven Komponente bei Richtungswechsel, Lokwechsel oder Lokumlauf.

    Args:
        params: Aufenthaltsparameter aus Konfiguration.
            Wenn das Argument fehlt, werden die Defaultwerte der PlanungParams-Klasse verwendet.
    """

    if params is None:
        params = PlanungParams

    if self.typ == 'H':
        result = params.mindestaufenthalt_planhalt
    elif 'E' in self.flags:
        result = params.mindestaufenthalt_ersatz
    elif 'F' in self.flags:
        result = params.mindestaufenthalt_fluegelung
    elif 'K' in self.flags:
        result = params.mindestaufenthalt_kupplung
    else:
        result = 0

    if 'L' in self.flags:
        result += params.mindestaufenthalt_lokumlauf
    elif 'R' in self.flags:
        result += params.mindestaufenthalt_richtungswechsel
    elif 'W' in self.flags:
        result += params.mindestaufenthalt_lokwechsel

    self.mindestaufenthalt = result

ZielGraphUngerichtet


              flowchart TD
              stskit.model.zielgraph.ZielGraphUngerichtet[ZielGraphUngerichtet]

              

              click stskit.model.zielgraph.ZielGraphUngerichtet href "" "stskit.model.zielgraph.ZielGraphUngerichtet"
            

Ungerichtete Variante von ZugGraph

Fuer gewisse Algorithmen kann es noetig sein, den Zielgraphen voruebergehend in einen ungerichteten umzuwandeln.

ZielLabelType


              flowchart TD
              stskit.model.zielgraph.ZielLabelType[ZielLabelType]

              

              click stskit.model.zielgraph.ZielLabelType href "" "stskit.model.zielgraph.ZielLabelType"
            

Ziellabelklasse

Das Ziellabel ist ähnlich wie die FahrplanZeileID aufgebaut. Für Ein- und Ausfahrten wird jedoch die Elementnummer statt des Anschlussnamens verwendet, weil Anschlussnamen mit Gleisnamen kollidieren können oder nicht explizit definiert sind.

Methods:

from_fahrplanzeile classmethod

from_fahrplanzeile(fid: FahrplanZeileID) -> ZielLabelType

Konstruktor aus einer Fahrplanzeilen-ID.

Der Ortsteil einer Fahrplanzeilen-ID bezieht sich immer auf ein Bahnhofsgleis (kein Anschlussgleis).

Source code in stskit/model/zielgraph.py
@classmethod
def from_fahrplanzeile(cls, fid: FahrplanZeileID) -> ZielLabelType:
    """
    Konstruktor aus einer Fahrplanzeilen-ID.

    Der Ortsteil einer Fahrplanzeilen-ID bezieht sich immer auf ein Bahnhofsgleis (kein Anschlussgleis).
    """
    return cls(fid.zid, fid.zeit, fid.plan)