diff --git a/lib/plant2dxf.py b/lib/plant2dxf.py index 33d03ea..ceb7574 100644 --- a/lib/plant2dxf.py +++ b/lib/plant2dxf.py @@ -19,9 +19,16 @@ import math # --------------------------------------------------------- Mapping TeileArt → Blockname BLOCKNAME_MAPPING = { "ILS 2.0 Kreisel": ["SP8", "AN8"] + #"ILS 2.0 Gefällestrecke": ["AE DS", "EE DS"] # Weitere Zuordnungen nach Bedarf } +# --------------------------------------------------------- On-the-fly-Typen (werden direkt im Code erzeugt) +ON_THE_FLY_TYPES = { + "ILS 2.0 Gefällestrecke", + # Weitere Typen nach Bedarf +} + # --------------------------------------------------------- Konstante Parameter ATTR_TAG = "TeileId" # Attributtag im Block RADIUS = 400 # Radius der Kreiselkreise (mm) @@ -84,6 +91,21 @@ def draw_kreisel_lines(msp, pos1, pos2): msp.add_line(p1a, p2a) msp.add_line(p1b, p2b) +def berechne_hoehe(csv_path): + y_werte = [] + with csv_path.open(newline="", encoding="utf-8") as fh: + reader = csv.DictReader(fh, delimiter=';') + for row in reader: + planquadrat = row.get("Planquadrat", "") + try: + _, y = extract_coords(planquadrat) + y_werte.append(y) + except Exception: + continue + if not y_werte: + raise ValueError("Keine Y-Koordinaten in der CSV gefunden!") + return max(y_werte) + def transform_coords(x: float, y: float, height: float) -> tuple[float, float]: """Transformiert Bildschirmkoordinaten (0,0 oben links) ins DXF-KoSy (0,0 unten links).""" return x, height - y @@ -130,6 +152,30 @@ def handle_standard(msp, blocknames, teileid, x, y, lib_doc, doc, verbose): print(f"[INFO] Block '{blockname}' (Standard) → {teileid} " f"({x:.1f}, {y:.1f})") +def handle_gefaellestrecke(msp, teileid, merkmale, x, y, verbose): + # Länge der Strecke (in Meter, Standard 10) + laenge_m = merkmale.get("Länge in Meter", "10").replace(",", ".") + try: + laenge = float(laenge_m) * 1000 # Meter → mm + except ValueError: + laenge = 10000 # Fallback 10 m + + # Drehung (Winkel in Grad, Standard 0) + try: + winkel = float(merkmale.get("Drehung", 0)) + except (ValueError, TypeError): + winkel = 0.0 + winkel_rad = math.radians(winkel) + + # Die Koordinaten (x, y) sind die Mitte der Strecke + halbe_laenge = laenge / 2 + dx = halbe_laenge * math.cos(winkel_rad) + dy = halbe_laenge * math.sin(winkel_rad) + start = (x - dx, y - dy) + ende = (x + dx, y + dy) + msp.add_line(start, ende) + if verbose: + print(f"[INFO] Gefällestrecke → {teileid} Linie von ({start[0]:.1f}, {start[1]:.1f}) nach ({ende[0]:.1f}, {ende[1]:.1f})") # --------------------------------------------------------- Hauptfunktion def main(csv_path: Path, lib_path: Path, cfg_path: Path, output_path: Path, verbose=False): @@ -152,22 +198,10 @@ def main(csv_path: Path, lib_path: Path, cfg_path: Path, msp = doc.modelspace() # CSV einlesen - # Zuerst alle Y-Werte sammeln, um die Höhe zu bestimmen - y_values = [] - with csv_path.open(newline="", encoding="utf-8") as fh: - reader = csv.DictReader(fh, delimiter=';') - for row in reader: - planquadrat = row["Planquadrat"] - try: - _, y = extract_coords(planquadrat) - y_values.append(y) - except Exception: - pass - if not y_values: - raise ValueError("Keine Y-Koordinaten in der CSV gefunden!") - height = max(y_values) + # Höhe bestimmen für Koordinaten-Transformation + height = berechne_hoehe(csv_path) - # Jetzt eigentliche Verarbeitung + # Verarbeitung der Blöcke with csv_path.open(newline="", encoding="utf-8") as fh: reader = csv.DictReader(fh, delimiter=';') for row in reader: @@ -183,21 +217,28 @@ def main(csv_path: Path, lib_path: Path, cfg_path: Path, print(f"[WARN] {teileid}: {e}") continue - # Blocknamen immer aus Mapping holen (ggf. Fallback auf Teileart) + # On-the-fly-Typen (werden direkt im Code erzeugt) + if teileart in ON_THE_FLY_TYPES: + if teileart == "ILS 2.0 Gefällestrecke": + handle_gefaellestrecke(msp, teileid, merkmale, x, y, verbose) + continue + # Hier können weitere on-the-fly-Typen ergänzt werden + + # Blocktypen aus Mapping blocknames = BLOCKNAME_MAPPING.get(teileart) - if not blocknames: - print(f"[WARN] Keine Blockzuordnung für TeileArt '{teileart}'. Überspringe '{teileid}'.") - continue - if isinstance(blocknames, str): - blocknames = [blocknames] - - # Spezialfall: ILS 2.0 Kreisel - if teileart == "ILS 2.0 Kreisel": - handle_kreisel(msp, blocknames, teileid, merkmale, row, x, y, height, lib_doc, doc, verbose) + if blocknames: + if isinstance(blocknames, str): + blocknames = [blocknames] + if teileart == "ILS 2.0 Kreisel": + handle_kreisel(msp, blocknames, teileid, merkmale, row, x, y, height, lib_doc, doc, verbose) + continue + # Standardfall + handle_standard(msp, blocknames, teileid, x, y, lib_doc, doc, verbose) continue - # Standardfall - handle_standard(msp, blocknames, teileid, x, y, lib_doc, doc, verbose) + # Weder on-the-fly noch im Mapping + print(f"[WARN] Keine Zuordnung für TeileArt '{teileart}'. Überspringe '{teileid}'.") + continue # DXF speichern doc.saveas(output_path)