Refactoring von gefällestrecke und elemente von csv behandlungen zu einer neuen File
This commit is contained in:
+10
-306
@@ -5,8 +5,6 @@ Erzeugt DXF-Elemente aus einer RuleDesigner-CSV.
|
||||
import os
|
||||
import sys
|
||||
import csv
|
||||
import json
|
||||
import re
|
||||
import argparse
|
||||
import configparser
|
||||
import ezdxf
|
||||
@@ -18,66 +16,12 @@ from utils import check_environment_var, setup_logger
|
||||
from Elemente import Kreisel, VarioFoerderer,Gefaehllestrecke,Angetriebene_Kurve,Bt_element,Omniflo, Eckrad
|
||||
import as_es_methoden
|
||||
import block_methoden
|
||||
# --------------------------------------------------------- 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
|
||||
import arbeiten_mit_csv
|
||||
|
||||
# --------------------------------------------------------- Konstante Parameter
|
||||
ATTR_TAG = "TeileId" # Attributtag im Block
|
||||
RADIUS = 400 # Radius der Kreiselkreise (mm)
|
||||
# --------------------------------------------------------- Hilfsfunktionen
|
||||
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 handle_ils_2_0_kreisel(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols,strecken_nachbarn,config,config_allgemein):
|
||||
"""Erstellt ein Kreisel in der neuen Dxf"""
|
||||
kreisel = Kreisel.Kreisel.from_merkmale(teileid, x, y, merkmale)
|
||||
@@ -343,94 +287,10 @@ def handle_ils_2_0_gefaellestrecke(msp, teileid, merkmale, x, y, doc, lib_doc, v
|
||||
hight_position = "higher"
|
||||
else:
|
||||
hight_position = "lower"
|
||||
if richtung2 == "DEFAULT":
|
||||
if richtung0 == "Vertikal":
|
||||
if x0_kreisel < x1_kreisel:
|
||||
position = hight_position + "_links"
|
||||
else:
|
||||
position = hight_position + "_rechts"
|
||||
else:
|
||||
if y0_kreisel > y1_kreisel:
|
||||
position = hight_position + "_higher"
|
||||
else:
|
||||
position = hight_position + "_lower"
|
||||
|
||||
if richtung0 == "Vertikal":
|
||||
if position == "lower_rechts" or position == "higher_links":
|
||||
gefaelle = "links"
|
||||
else:
|
||||
gefaelle = "rechts"
|
||||
elif richtung0 == "Horizontal":
|
||||
if position == "lower_lower" or position == "higher_higher":
|
||||
gefaelle = "oben"
|
||||
else:
|
||||
gefaelle = "unten"
|
||||
# vertausch der drehung und der höhe für die namens gebung des blockes
|
||||
if (position == "higher_rechts" or position == "lower_rechts" or position=="higher_lower" or position== "lower_lower") and drehung0 != drehung1 and am_kreisel == 0:
|
||||
drehung_2 = drehung0
|
||||
drehung0 = drehung1
|
||||
drehung1= drehung_2
|
||||
if hight_position == "higher":
|
||||
hight_position = "lower"
|
||||
else:
|
||||
hight_position = "higher"
|
||||
|
||||
# austausch der werte damit immer davon ausgehen dass der 1 kreisel in unserer Liste am Kreisel verbuden ist
|
||||
if kreisel_verbunden == 1 and am_kreisel ==2:
|
||||
am_kreisel == 1
|
||||
drehung_2 = drehung0
|
||||
drehung0 = drehung1
|
||||
drehung1= drehung_2
|
||||
if hight_position == "higher":
|
||||
hight_position = "lower"
|
||||
else:
|
||||
hight_position = "higher"
|
||||
else:
|
||||
if richtung2 == "Vertikal":
|
||||
if x0_kreisel < x1_kreisel:
|
||||
position = hight_position + "_links"
|
||||
else:
|
||||
position = hight_position + "_rechts"
|
||||
else:
|
||||
if y0_kreisel > y1_kreisel:
|
||||
position = hight_position + "_higher"
|
||||
else:
|
||||
position = hight_position + "_lower"
|
||||
|
||||
if richtung2 == "Vertikal":
|
||||
if position == "lower_rechts" or position == "higher_links":
|
||||
gefaelle = "links"
|
||||
else:
|
||||
gefaelle = "rechts"
|
||||
elif richtung2 == "Horizontal":
|
||||
if position == "lower_lower" or position == "higher_higher":
|
||||
gefaelle = "oben"
|
||||
else:
|
||||
gefaelle = "unten"
|
||||
# austausch der werte damit immer davon ausgehen dass der 1 kreisel in unserer Liste am Kreisel verbuden ist
|
||||
if am_kreisel == 2:
|
||||
am_kreisel = 1
|
||||
drehung_2 = drehung0
|
||||
drehung0 = drehung1
|
||||
drehung1= drehung_2
|
||||
if hight_position == "higher":
|
||||
hight_position = "lower"
|
||||
else:
|
||||
hight_position = "higher"
|
||||
# Erstellung der Rotation
|
||||
if gefaelle == "oben":
|
||||
rotation = 0
|
||||
elif gefaelle == "unten" :
|
||||
rotation = 180
|
||||
elif gefaelle == "links" :
|
||||
rotation = 90
|
||||
elif gefaelle == "rechts" :
|
||||
rotation = 270
|
||||
|
||||
rotation, drehung0, drehung1, hight_position = Gefaehllestrecke.Gefaellestrecke.rotation_mit_zwei_verbunden(gefaellestrecke_nachbarn, richtung2, richtung0, am_kreisel, kreisel_verbunden, hight_position)
|
||||
#geben der richtung2 eines wertes außer default wenn beide kreisel die gleiche richung haben
|
||||
if (kreisel_verbunden == 1 and richtung2 =="DEFAULT"):
|
||||
richtung2 = richtung0
|
||||
|
||||
if richtung2 == "DEFAULT":
|
||||
blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaehlle}_{drehung0}_{drehung1}_{hight_position}_{verbunden_am_einen}"
|
||||
else:
|
||||
@@ -489,6 +349,8 @@ def handle_ils_2_0_gefaellestrecke(msp, teileid, merkmale, x, y, doc, lib_doc, v
|
||||
line.translate(-x,-y,-hoehe_gefaehlle)
|
||||
block.add_entity(line)
|
||||
msp.add_blockref(blockname,(x,y,hoehe_gefaehlle),dxfattribs={"rotation": rotation,"layer": gefaelle_layer})
|
||||
|
||||
|
||||
|
||||
def anzahl_seperatoren_oder_scan(msp, x, y, doc, lib_doc, klassen_objekt, hoehe, rotation):
|
||||
"""Importiert alle seperatoren und/oder scanner für das nötige objekt"""
|
||||
@@ -950,19 +812,6 @@ def handle_omniflo(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols,
|
||||
layer, color = block_methoden.get_insert_color_layer(lib_doc, omniflo_objekt.sivasnummer)
|
||||
msp.add_blockref(blockname, (x, y,omniflo_objekt.hoehe), dxfattribs={"rotation": rotation,"layer": layer, "color": color})
|
||||
|
||||
|
||||
def normalize_func_name(name):
|
||||
return (
|
||||
name.replace('ä', 'ae')
|
||||
.replace('ö', 'oe')
|
||||
.replace('ü', 'ue')
|
||||
.replace('ß', 'ss')
|
||||
.replace(' ', '_')
|
||||
.replace('.', '_')
|
||||
.replace('-', '_')
|
||||
.lower()
|
||||
)
|
||||
|
||||
def get_libfile_cfg(teileart, cfg_path):
|
||||
"""Liest den Bibliotheksdateinamen für eine TeileArt aus der allgemein.cfg."""
|
||||
parser = configparser.ConfigParser()
|
||||
@@ -975,151 +824,6 @@ def get_libfile_cfg(teileart, cfg_path):
|
||||
return parser.get(section, "libfile", fallback=None)
|
||||
return None
|
||||
|
||||
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
|
||||
|
||||
# --------------------------------------------------------- Hauptfunktion
|
||||
def main(csv_path: Path, lib_path: Path, cfg_path: Path, allgemein_cfg_path: Path,
|
||||
output_path: Path, output_path_jason: Path, verbose=False, logger=None ):
|
||||
@@ -1152,7 +856,7 @@ def main(csv_path: Path, lib_path: Path, cfg_path: Path, allgemein_cfg_path: Pat
|
||||
|
||||
# gibt zu jeder ShapeId einer Gefällestrecke zurück, ob sich der jeweilige Kreisel im UZ oder GUZ dreht
|
||||
# rot_of_gf["shape_3ae53a7b-efb8-f66b-eadc-20b99f949ef1"] = ('UZ', 'GUZ')
|
||||
strecken_nachbarn = get_nachbar_information(csv_path)
|
||||
strecken_nachbarn = arbeiten_mit_csv.get_nachbar_information(csv_path)
|
||||
|
||||
# Verarbeitung der Blöcke
|
||||
|
||||
@@ -1163,10 +867,10 @@ def main(csv_path: Path, lib_path: Path, cfg_path: Path, allgemein_cfg_path: Pat
|
||||
teileart = row["TeileArt"].strip()
|
||||
teileid = row["TeileId"].strip()
|
||||
planquadrat = row["Planquadrat"]
|
||||
merkmale = parse_merkmale(row.get("Merkmale", ""))
|
||||
merkmale = arbeiten_mit_csv.parse_merkmale(row.get("Merkmale", ""))
|
||||
merkmale["bezeichner"] = bezeichner
|
||||
try:
|
||||
x, y = extract_coords(planquadrat)
|
||||
x, y = arbeiten_mit_csv.extract_coords(planquadrat)
|
||||
|
||||
except Exception as e:
|
||||
msg = f"[WARN] {teileid}: {e}"
|
||||
@@ -1199,9 +903,9 @@ def main(csv_path: Path, lib_path: Path, cfg_path: Path, allgemein_cfg_path: Pat
|
||||
print(f"[INFO] Keine Bibliothek gefunden unter {lib_path}. Komplexe Formen werden übersprungen.")
|
||||
|
||||
# Funktions-Dispatch: handle_<teileart> (mit _ statt Leerzeichen und Punkten, alles klein)
|
||||
func_name = f'handle_{normalize_func_name(teileart)}'
|
||||
func_name = f'handle_{arbeiten_mit_csv.normalize_func_name(teileart)}'
|
||||
handler = globals().get(func_name)
|
||||
symbols = get_shape_cfg(teileart, cfg_path, logger=logger)
|
||||
symbols = arbeiten_mit_csv.get_shape_cfg(teileart, cfg_path, logger=logger)
|
||||
# Mapping für Omniflo-Typen
|
||||
if func_name.startswith('handle_omniflo') or func_name.startswith('handle_tef'):
|
||||
handler = globals().get('handle_omniflo')
|
||||
|
||||
Reference in New Issue
Block a user