# -*- coding: utf-8 -*- import os import sys import csv import json import re import configparser from pathlib import Path from lib.utils import check_environment_var, setup_logger from lib.Elemente import Kreisel, VarioFoerderer,Gefaellestrecke,Angetriebene_Kurve,Bt_element,Omniflo, Eckrad # --------------------------------------------------------- CFG-Leser für shapes.cfg def get_shape_cfg(teileart, cfg_path, logger=None): parser = configparser.ConfigParser() try: with open(cfg_path, encoding='utf-8') as f: parser.read_file(f) except Exception as e: msg = f"Fehler beim Lesen der Config-Datei {cfg_path}: {e}" if logger: logger.error(msg) else: print(msg) return [] section = teileart if section not in parser: return [] # Blöcke items = parser.get(section, "items", fallback="").replace('"', '').split(",") blocks = [item.strip() for item in items if item.strip()] symbols = [] for i, name in enumerate(blocks): # Offset offset_key = f"offset_symb{i+1}" offset_str = parser.get(section, offset_key, fallback="0,0") try: ox, oy = [float(x) for x in offset_str.split(",")] except Exception: ox, oy = 0.0, 0.0 # Rotation rot_key = f"rot_symb{i+1}" rot_str = parser.get(section, rot_key, fallback="0.0") try: rot = float(rot_str) except Exception: rot = 0.0 symbols.append({ "name": name, "offset": (ox, oy), "rotation": rot }) return symbols def extract_coords(planquadrat: str) -> tuple[float, float]: """Extrahiert X/Y Koordinaten aus PlanquadratString.""" m = re.search(r"X:(\d+[\.,]?\d*)\s+Y:(\d+[\.,]?\d*)", planquadrat) if not m: raise ValueError(f"Koordinaten nicht gefunden in: '{planquadrat}'") x, y = m.groups() return float(x.replace(",", ".")), float(y.replace(",", ".")) def parse_merkmale(merkmale_str: str) -> dict: """Parst Merkmale-JSON-String in dict; bei Fehler → leeres Dict.""" try: return json.loads(merkmale_str) except json.JSONDecodeError: return {} def get_nachbar_information(csv_path:Path) -> dict: """Gibt die Art und nötige Elemente den Nachbardateien zurück""" geraden = [] kreisel =[] strecken_nachbarn = [] angetriebene_kurve= [] eckrad_dic= [] """Gib für jede gefällestrecke zurück welche Drehrichtung die benachbarten Kreisel haben """ with csv_path.open(newline="", encoding="utf-8") as fh: reader = csv.DictReader(fh, delimiter=';') for row in reader: bezeichner = row["TeileArt"].strip() if bezeichner == "ILS 2.0 Gefällestrecke": Id = row["TeileId"].strip() NachbarIds = row["NachbarIds"].strip() geraden.append({"Id": Id, "NachbarIds": NachbarIds}) if bezeichner == "ILS 2.0 Kreisel" or bezeichner == "ILS 2.0 Kreisel mit Pin": Id = row["TeileId"].strip() planquadrat = row["Planquadrat"] x, y = extract_coords(planquadrat) merkmale = parse_merkmale(row.get("Merkmale", "")) # Erstelle Kreisel-Objekt kreisel_obj = Kreisel.Kreisel.from_merkmale(Id, x, y, merkmale) # Für Kompatibilität auch als Dict speichern (für bestehende Code-Stellen) kreisel.append({ "Id": Id, "drehung": kreisel_obj.drehrichtung, "höhe": kreisel_obj.hoehe, "x": kreisel_obj.x, "y": kreisel_obj.y, "rotation": kreisel_obj.drehung, "abstand": str(kreisel_obj.abstand / 1000) # Zurück in Meter als String }) if bezeichner =="ILS 2.0 VarioFoerderer": Id = row["TeileId"].strip() NachbarIds = row["NachbarIds"].strip() merkmale = parse_merkmale(row.get("Merkmale", "")) planquadrat = row["Planquadrat"] x, y = extract_coords(planquadrat) foerderer_objekt = VarioFoerderer.VarioFoerderer.from_merkmale(Id, x,y,merkmale) winkel = foerderer_objekt.winkel h0 = foerderer_objekt.h0 h1 = foerderer_objekt.h1 foerderrichtung = foerderer_objekt.foerderer_richtung geraden.append({"Id": Id,"NachbarIds":NachbarIds, "Winkel":winkel, "h0": h0,"h1": h1,"Foerderrichtung":foerderrichtung,"X_foerderer": x,"Y_foerderer": y }) if bezeichner =="ILS 2.0 Kurve angetrieben": Id = row["TeileId"].strip() planquadrat = row["Planquadrat"] x, y = extract_coords(planquadrat) merkmale = parse_merkmale(row.get("Merkmale", "")) kurve_angetrieben = Angetriebene_Kurve.Angetriebene_Kurve.from_merkmale(Id,x,y,merkmale) h0 = kurve_angetrieben.hoehe0 h1 = kurve_angetrieben.hoehe1 kurvenrichtung = kurve_angetrieben.kurvenrichtung tefkurve = kurve_angetrieben.antrieb kurve_winkel = kurve_angetrieben.winkel angetriebene_kurve.append({"Id": Id,"H0": h0,"H1":h1,"kurvenrichtung":kurvenrichtung,"Tefkurve": tefkurve,"Kurvenwinkel": kurve_winkel,"X_angetrieben":x,"Y_angetrieben":y}) if bezeichner =="ILS 2.0 Eckrad": Id = row["TeileId"].strip() planquadrat = row["Planquadrat"] x, y = extract_coords(planquadrat) merkmale = parse_merkmale(row.get("Merkmale", "")) eckrad_att = Eckrad.Eckrad.from_merkmale(Id,x,y,merkmale) eckrad_dic.append({"Id": Id,"H0": eckrad_att.hoehe,"Eckrad_x": x,"Eckrad_y": y}) for gerade in geraden: anweisungen = 0 voerder_anweisung = 0 geraden_anweisung = 0 eckrad_anweisung = 0 eintrag = {"Id": gerade["Id"]} for foerderer in angetriebene_kurve: if foerderer["Id"] in gerade["NachbarIds"]: if voerder_anweisung == 0: eintrag["X_angetrieben"] = foerderer.get("X_angetrieben") eintrag["Y_angetrieben"] = foerderer.get("Y_angetrieben") eintrag["vario_hoehe_0"] = foerderer.get("H0") eintrag["vario_hoehe_1"] = foerderer.get("H1") eintrag["Kurvenrichtung"] = foerderer.get("kurvenrichtung") eintrag["Tefkurve"] = foerderer.get("Tefkurve") eintrag["Kurvenwinkel"] = foerderer.get("Kurvenwinkel") voerder_anweisung = 1 elif voerder_anweisung ==1: eintrag["X_angetrieben_1"] = foerderer.get("X_angetrieben") eintrag["Y_angetrieben_1"] = foerderer.get("Y_angetrieben") eintrag["vario_hoehe_0_1"] = foerderer.get("H0") eintrag["vario_hoehe_1_1"] = foerderer.get("H1") eintrag["Kurvenrichtung_1"] = foerderer.get("kurvenrichtung") eintrag["Tefkurve_1"] = foerderer.get("Tefkurve") eintrag["Kurvenwinkel_1"] = foerderer.get("Kurvenwinkel") for eckrad in eckrad_dic: if eckrad["Id"] in gerade["NachbarIds"]: if eckrad_anweisung == 0: eintrag["Eckrad_x"] = eckrad.get("Eckrad_x") eintrag["Eckrad_y"] = eckrad.get("Eckrad_y") eintrag["Eckrad_höhe"] = eckrad.get("H0") eckrad_anweisung = 1 elif eckrad_anweisung == 1: eintrag["Eckrad_x_1"] = eckrad.get("Eckrad_x") eintrag["Eckrad_y_1"] = eckrad.get("Eckrad_y") eintrag["Eckrad_höhe_1"] = eckrad.get("H0") for kreis in kreisel: if kreis["Id"] in gerade["NachbarIds"]: if anweisungen == 0: eintrag["Drehung0"] = kreis.get("drehung") eintrag["Hoehe0"] = kreis.get("höhe") eintrag["x0"] = kreis.get("x") eintrag["y0"] = kreis.get("y") eintrag["rotation0"] = kreis.get("rotation") eintrag["abstand0"] = kreis.get("abstand") anweisungen = 1 elif anweisungen == 1: eintrag["Drehung1"] = kreis.get("drehung") eintrag["Hoehe1"] = kreis.get("höhe") eintrag["x1"] = kreis.get("x") eintrag["y1"] = kreis.get("y") eintrag["rotation1"] = kreis.get("rotation") eintrag["abstand1"] = kreis.get("abstand") break if(gerade.get("Winkel") != None ): for vario_gerade in geraden: if vario_gerade["Id"] in gerade["NachbarIds"] and vario_gerade.get("Winkel") != None: if geraden_anweisung == 0: eintrag["X_foerderer"] = vario_gerade.get("X_foerderer") eintrag["Y_foerderer"] = vario_gerade.get("Y_foerderer") eintrag["Winkel"] = vario_gerade.get("Winkel") eintrag["h0"] = vario_gerade.get("h0") eintrag["h1"] = vario_gerade.get("h1") eintrag["Foerderrichtung"] = vario_gerade.get("Foerderrichtung") geraden_anweisung =1 elif geraden_anweisung == 1: eintrag["X_foerderer_2"] = vario_gerade.get("X_foerderer") eintrag["Y_foerderer_2"] = vario_gerade.get("Y_foerderer") eintrag["Winkel_2"] = vario_gerade.get("Winkel") eintrag["h0_2"] = vario_gerade.get("h0") eintrag["h1_2"] = vario_gerade.get("h1") eintrag["Foerderrichtung_2"] = vario_gerade.get("Foerderrichtung") break strecken_nachbarn.append(eintrag) return strecken_nachbarn def normalize_func_name(name): return ( name.replace('ä', 'ae') .replace('ö', 'oe') .replace('ü', 'ue') .replace('ß', 'ss') .replace(' ', '_') .replace('.', '_') .replace('-', '_') .lower() )