|
| 1 | +from enum import Enum, auto |
| 2 | +from typing import Dict, List, Tuple |
| 3 | + |
| 4 | +from yaramo.base_element import BaseElement |
| 5 | +from yaramo.edge import Edge |
| 6 | +from yaramo.node import Node |
| 7 | + |
| 8 | + |
| 9 | +class TrackType(Enum): |
| 10 | + Hauptgleis = auto() |
| 11 | + Durchgehendes_Hauptgleis = auto() |
| 12 | + Streckengleis = auto() |
| 13 | + Anschlussgleis = auto() |
| 14 | + Nebengleis = auto() |
| 15 | + sonstige = auto() |
| 16 | + |
| 17 | + |
| 18 | +class Track(BaseElement): |
| 19 | + def __init__(self, track_type, **kwargs): |
| 20 | + super().__init__(**kwargs) |
| 21 | + self.track_type: TrackType = track_type |
| 22 | + self.edge_sections: Dict[Edge, Tuple[float, float]] = {} |
| 23 | + |
| 24 | + def add_edge_section(self, edge: Edge, section_start: float, section_end: float): |
| 25 | + self.edge_sections[edge] = (section_start, section_end) |
| 26 | + |
| 27 | + @property |
| 28 | + def edges(self) -> List[Edge]: |
| 29 | + return list(self.edge_sections.keys()) |
| 30 | + |
| 31 | + def get_edges_in_order(self) -> List[Edge]: |
| 32 | + if len(self.edges) <= 1: |
| 33 | + return self.edges |
| 34 | + |
| 35 | + def _count_node_occurrences_in_edges(_node: Node): |
| 36 | + _count = 0 |
| 37 | + for _edge in self.edges: |
| 38 | + if _node == _edge.node_a: |
| 39 | + _count += 1 |
| 40 | + if _node == _edge.node_b: |
| 41 | + _count += 1 |
| 42 | + return _count |
| 43 | + |
| 44 | + previous_edge: Edge | None = self.edges[0] |
| 45 | + next_node: Node | None = None |
| 46 | + |
| 47 | + for edge in self.edges: |
| 48 | + count_a = _count_node_occurrences_in_edges(edge.node_a) |
| 49 | + count_b = _count_node_occurrences_in_edges(edge.node_b) |
| 50 | + if count_a == 1 and count_b == 1: |
| 51 | + raise ValueError("Edges of Track separated") |
| 52 | + if count_a == 1 and count_b > 1: |
| 53 | + previous_edge = edge |
| 54 | + next_node = edge.node_b |
| 55 | + break |
| 56 | + if count_a > 1 and count_b == 1: |
| 57 | + previous_edge = edge |
| 58 | + next_node = edge.node_a |
| 59 | + break |
| 60 | + |
| 61 | + edges_in_order: List[Edge] = [previous_edge] |
| 62 | + |
| 63 | + while len(edges_in_order) < len(self.edges): |
| 64 | + next_edge = None |
| 65 | + for edge in self.edges: |
| 66 | + if edge.is_node_connected(next_node) and not edge == previous_edge: |
| 67 | + next_edge = edge |
| 68 | + break |
| 69 | + |
| 70 | + edges_in_order.append(next_edge) |
| 71 | + next_node = next_edge.get_other_node(next_node) |
| 72 | + previous_edge = next_edge |
| 73 | + |
| 74 | + return edges_in_order |
0 commit comments