From d29cf07cfc021408ba1c0689052c5696441b9b30 Mon Sep 17 00:00:00 2001 From: Paul Wolok Date: Wed, 1 Oct 2025 14:16:22 +0200 Subject: [PATCH] Erste Version von Gefaellestrecke, man kann noch nicht kreisel mit einander verbinden --- cfg/shapes.cfg | 2 +- lib/plant2dxf.py | 286 +++++++++++++++++++++++++++++++---------------- 2 files changed, 189 insertions(+), 99 deletions(-) diff --git a/cfg/shapes.cfg b/cfg/shapes.cfg index 674844b..c70a338 100644 --- a/cfg/shapes.cfg +++ b/cfg/shapes.cfg @@ -12,5 +12,5 @@ offset_symb2 = 0,1000 rot_symb1 = 0.0 rot_symb2 = 0.0 asoffset = 537.90 -esoffset = 479.93 +esoffset = 479.95 additionaloffset = 59.48 diff --git a/lib/plant2dxf.py b/lib/plant2dxf.py index b408260..5dced24 100644 --- a/lib/plant2dxf.py +++ b/lib/plant2dxf.py @@ -160,7 +160,7 @@ 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, y -def handle_ils_2_0_kreisel(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, richtung,config): +def handle_ils_2_0_kreisel(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols,gefaellestrecken_nachbarn,config): abstand_m = merkmale.get( "Abstand (Kreiselachse A - Kreiselachse) in Meter", "20" ).replace(",", ".") @@ -188,7 +188,7 @@ def handle_ils_2_0_kreisel(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, offset = sym["offset"] rotation = sym["rotation"] if i < len(positions): - pos = (positions[i][0] + offset[0], positions[i][1] + offset[1]) + pos = (positions[i][0] + offset[0], positions[i][1] + offset[1],float(merkmale.get("Höhe in m"))*1000) import_block(blockname, lib_doc, doc) blockref_layer = get_layer(doc, lib_doc, blockname) bref = msp.add_blockref(blockname, pos, dxfattribs={"rotation": merkmale.get("Drehung"), "layer" : blockref_layer}) @@ -281,110 +281,183 @@ def handle_standard(msp, blocknames, teileid, x, y, lib_doc, doc, verbose): f"({x:.1f}, {y:.1f})") -def handle_ils_2_0_gefaellestrecke(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, richtung,config): - # blocks: [block1, block2], offsets: [(ox1, oy1), (ox2, oy2)] - # Länge der Strecke (in Meter, Standard 10) +def handle_ils_2_0_gefaellestrecke(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, gefaellestrecken_nachbarn,config): + #Vorbereitung der attributen asoffset = float(config.get("ILS 2.0 Gefällestrecke", "asoffset")) esoffset = float(config.get("ILS 2.0 Gefällestrecke", "esoffset")) - upper_hight = float(merkmale.get("Höhe oben")) *1000 - lower_hight = float(merkmale.get("Höhe unten")) * 1000 - hight = (upper_hight + lower_hight)/2 - - + upper_hoehe_gefaehlle= float(merkmale.get("Höhe oben")) *1000 + lower_hoehe_gefaehlle = float(merkmale.get("Höhe unten")) * 1000 + hoehe_gefaehlle = (upper_hoehe_gefaehlle + lower_hoehe_gefaehlle)/2 + for nachbarn in gefaellestrecken_nachbarn: + if teileid == nachbarn.get("Id"): + gefaellestrecke_nachbarn = nachbarn + break + drehung0 =gefaellestrecke_nachbarn.get("Drehung0") + drehung1 = gefaellestrecke_nachbarn.get("Drehung1") + hoehe0 = gefaellestrecke_nachbarn.get("Hoehe0") + hoehe1 = gefaellestrecke_nachbarn.get("Hoehe1") + x0_kreisel = float(gefaellestrecke_nachbarn.get("x0")) + y0_kreisel = float(gefaellestrecke_nachbarn.get("y0")) + x1_kreisel = float(gefaellestrecke_nachbarn.get("x1")) + y1_kreisel = float(gefaellestrecke_nachbarn.get("y1")) + richtung0 = float(gefaellestrecke_nachbarn.get("rotation0")) + richtung1 = float(gefaellestrecke_nachbarn.get("rotation1")) 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 - blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hight}" - # if blockname not in doc.blocks: - # block = doc.blocks.new(name=blockname, base_point=(0,0,0)) - # halbe_laenge = laenge / 2 - - # dy = halbe_laenge * math.cos(0) - # start = (x , y + dy - asoffset,upper_hight) - # ende = (x , y - dy + esoffset,lower_hight) - # line = Line.new(dxfattribs={"start": start, "end": ende}) - # copy= line.copy() - - # copy.translate(-x,-y,-hight) - # block.add_entity(copy) - # a = "200000241_AS-Element_90_rechts" - # import_block(a,lib_doc,doc) - # b = "200000146_ES-Element_90_rechts" - # import_block(b,lib_doc,doc) - # block.add_blockref(a,(start[0]-x ,start[1]+asoffset -y,start[2] -hight)) - # block.add_blockref(b, (ende[0]-x ,ende[1]-esoffset-y ,ende[2] -hight)) - - # if blockname not in doc.blocks: - # block = doc.blocks.new(name=blockname, base_point=(0,0,0)) - # halbe_laenge = laenge / 2 - - # dy = halbe_laenge * math.cos(0) - # start = (x , y + dy - asoffset,upper_hight) - # ende = (x , y - dy + esoffset,lower_hight) - # line = Line.new(dxfattribs={"start": start, "end": ende}) - # copy= line.copy() - - # copy.translate(-x,-y,-hight) - # block.add_entity(copy) - # a = "200000241_AS-Element_90_rechts" - # import_block(a,lib_doc,doc) - # b = "400102632_ES-Element_90_links" - # import_block(b,lib_doc,doc) - # block.add_blockref(a,(start[0]-x ,start[1]+asoffset -y,start[2])) - # block.add_blockref(b, (ende[0]-x ,ende[1]- esoffset-y,ende[2]),dxfattribs={"rotation": 180}) - # if blockname not in doc.blocks: - # block = doc.blocks.new(name=blockname, base_point=(0,0,0)) - # halbe_laenge = laenge / 2 - - # dy = halbe_laenge * math.cos(0) - # start = (x , y + dy - esoffset,upper_hight) - # ende = (x , y - dy + asoffset,lower_hight) - # line = Line.new(dxfattribs={"start": start, "end": ende}) - # copy= line.copy() + + #Berechnung des Gefälles + if hoehe0 > hoehe1: + hight_position = "higher" + else: + hight_position = "lower" + if richtung0 == 90.0 or richtung0 == 270.0: + 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 == 90.0 or richtung0 == 270.0: + if position == "lower_rechts" or position == "higher_links": + gefaelle = "links" + else: + gefaelle = "rechts" + elif richtung0 == 0.0 or richtung0 == 180.0: + if position == "lower_lower" or position == "higher_higher": + gefaelle = "oben" + else: + gefaelle = "unten" + + #Wechsel das die Drehung des obersten oder des Linkens Kreisels immer als erstes steht für die Bennenung des Blockes und dem entsprchend + #wird auch getauscht in welcher hohen position es ist + if (position == "higher_rechts" or position == "lower_rechts" or position=="higher_lower" or position== "lower_lower") and drehung0 != drehung1: + drehung_2 = drehung0 + drehung0 = drehung1 + drehung1= drehung_2 + if hight_position == "higher": + hight_position = "lower" + else: + hight_position = "higher" + + # + blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaehlle}_{drehung0}_{drehung1}_{hight_position}" + if gefaelle == "oben": + rotation = 0 + elif gefaelle == "unten" : + rotation = 180 + elif gefaelle == "links" : + rotation = 90 + elif gefaelle == "rechts" : + rotation = 270 + gefaellegerade_erstellung(x, y, doc, lib_doc, asoffset, esoffset, upper_hoehe_gefaehlle, lower_hoehe_gefaehlle, hoehe_gefaehlle, drehung0, drehung1, laenge, hight_position, blockname) + - # copy.translate(-x ,-y,-hight) - # block.add_entity(copy) - # a = "200000217_AS-Element_90_links" - # import_block(a,lib_doc,doc) - # b = "400102632_ES-Element_90_links" - # import_block(b,lib_doc,doc) + + bref =msp.add_blockref(blockname,(x,y,hoehe_gefaehlle),dxfattribs={"rotation": rotation}) + bref.add_attrib( + tag= "NAME", + text= merkmale.get("bezeichner"), + insert = (x,y) - # block.add_blockref(a,(start[0]-x ,start[1]+esoffset -y,start[2]),dxfattribs={"rotation": 180}) - # block.add_blockref(b, (ende[0]-x ,ende[1]-asoffset -y,ende[2]),dxfattribs={"rotation": 180}) - - if blockname not in doc.blocks: + ) + + +def gefaellegerade_erstellung(x, y, doc, lib_doc, asoffset, esoffset, upper_hoehe_gefaehlle, lower_hoehe_gefaehlle, hoehe_gefaehlle, drehung0, drehung1, laenge, hight_position, blockname): + if blockname not in doc.blocks and drehung0 == "GUZS" and drehung1 == "GUZS" : block = doc.blocks.new(name=blockname, base_point=(0,0,0)) halbe_laenge = laenge / 2 dy = halbe_laenge * math.cos(0) - start = (x , y + dy - esoffset,upper_hight) - ende = (x , y - dy + asoffset,lower_hight) + start = (x , y + dy - asoffset,upper_hoehe_gefaehlle) + ende = (x , y - dy + esoffset,lower_hoehe_gefaehlle) line = Line.new(dxfattribs={"start": start, "end": ende}) copy= line.copy() - copy.translate(-x ,-y,-hight) + copy.translate(-x,-y,-hoehe_gefaehlle) block.add_entity(copy) - a = "200000217_AS-Element_90_links" - import_block(a,lib_doc,doc) - b = "200000146_ES-Element_90_rechts" - import_block(b,lib_doc,doc) - - block.add_blockref(a,(start[0]-x ,start[1]+asoffset -y,start[2]),dxfattribs={"rotation": 180}) + block_as = "200000241_AS-Element_90_rechts" + import_block(block_as,lib_doc,doc) + block_es = "200000146_ES-Element_90_rechts" + import_block(block_es,lib_doc,doc) + block.add_blockref(block_as,(start[0]-x ,start[1]+asoffset -y,start[2] -hoehe_gefaehlle)) + block.add_blockref(block_es, (ende[0]-x ,ende[1]-esoffset-y ,ende[2] -hoehe_gefaehlle)) + + if blockname not in doc.blocks and ((drehung0 == "GUZS" and drehung1 == "UZS" and hight_position == "higher")or (drehung0 == "UZS" and drehung1 == "GUZS" and hight_position == "lower")): + block = doc.blocks.new(name=blockname, base_point=(0,0,0)) + halbe_laenge = laenge / 2 - block.add_blockref(b, (ende[0]-x ,ende[1]-esoffset -y,ende[2]),) + dy = halbe_laenge * math.cos(0) + start = (x , y + dy - asoffset,upper_hoehe_gefaehlle) + ende = (x , y - dy + esoffset,lower_hoehe_gefaehlle) + line = Line.new(dxfattribs={"start": start, "end": ende}) + copy= line.copy() + copy.translate(-x,-y,-hoehe_gefaehlle) + block.add_entity(copy) + block_as = "200000241_AS-Element_90_rechts" + import_block(block_as,lib_doc,doc) + block_es = "400102632_ES-Element_90_links" + import_block(block_es,lib_doc,doc) + block.add_blockref(block_as,(start[0]-x ,start[1]+asoffset -y,start[2])) + block.add_blockref(block_es, (ende[0]-x ,ende[1]- esoffset-y,ende[2]),dxfattribs={"rotation": 180}) + + + if blockname not in doc.blocks and drehung0 == "UZS" and drehung1 == "UZS": + block = doc.blocks.new(name=blockname, base_point=(0,0,0)) + halbe_laenge = laenge / 2 + + dy = halbe_laenge * math.cos(0) + start = (x , y + dy - asoffset,upper_hoehe_gefaehlle) + ende = (x , y - dy + esoffset,lower_hoehe_gefaehlle) + line = Line.new(dxfattribs={"start": start, "end": ende}) + copy= line.copy() + + copy.translate(-x ,-y,-hoehe_gefaehlle) + block.add_entity(copy) + block_as = "200000217_AS-Element_90_links" + import_block(block_as,lib_doc,doc) + block_es = "400102632_ES-Element_90_links" + import_block(block_es,lib_doc,doc) + + block.add_blockref(block_as,(start[0]-x ,start[1]+asoffset -y,start[2]),dxfattribs={"rotation": 180}) + + block.add_blockref(block_es, (ende[0]-x ,ende[1]-esoffset -y,ende[2]),dxfattribs={"rotation": 180}) + + + if blockname not in doc.blocks and ((drehung0 == "UZS" and drehung1 == "GUZS" and hight_position== "higher")or (drehung0 == "GUZS" and drehung1 == "UZS" and hight_position == "lower")): + block = doc.blocks.new(name=blockname, base_point=(0,0,0)) + halbe_laenge = laenge / 2 + + dy = halbe_laenge * math.cos(0) + start = (x , y + dy - asoffset,upper_hoehe_gefaehlle) + ende = (x , y - dy + esoffset,lower_hoehe_gefaehlle) + line = Line.new(dxfattribs={"start": start, "end": ende}) + copy= line.copy() + + copy.translate(-x ,-y,-hoehe_gefaehlle) + block.add_entity(copy) + block_as = "200000217_AS-Element_90_links" + import_block(block_as,lib_doc,doc) + block_es = "200000146_ES-Element_90_rechts" + import_block(block_es,lib_doc,doc) + + block.add_blockref(block_as,(start[0]-x ,start[1]+asoffset -y,start[2]),dxfattribs={"rotation": 180}) + + block.add_blockref(block_es, (ende[0]-x ,ende[1]-esoffset -y,ende[2])) - msp.add_blockref(blockname,(x,y,hight),dxfattribs={"rotation": merkmale.get("Drehung")}) - if verbose: - print(f"[INFO] Gefällestrecke → {teileid} Linie von ({start[0]:.1f}, {start[1]:.1f}) nach ({ende[0]:.1f}, {ende[1]:.1f})") -def handle_omniflo(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, richtung,config): +def handle_omniflo(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, gefaellestrecken_nachbarn,config): """ Für Omniflo Gerade: zeichnet eine Linie (Mitte = Koordinate, Länge und Winkel aus Merkmale). Für alle anderen Omniflo-Typen: Block mit SivasNummer an den Koordinaten. @@ -503,9 +576,9 @@ def get_libfile_cfg(teileart, cfg_path): def get_rotations_of_gefaellestrecke(csv_path:Path) -> dict: - gefaehlleStrecken = dict() - kreisel =dict() - richtung = dict() + gefaehlleStrecken = [] + kreisel =[] + gefaellestrecken_nachbarn = [] anweisungen = 0 """Gib für jede gefällestrecke zurück welche Drehrichtung die benachbarten Kreisel haben """ with csv_path.open(newline="", encoding="utf-8") as fh: @@ -515,24 +588,41 @@ def get_rotations_of_gefaellestrecke(csv_path:Path) -> dict: if bezeichner == "ILS 2.0 Gefällestrecke": Id = row["TeileId"].strip() NachbarIds = row["NachbarIds"].strip() - gefaehlleStrecken.append({"Ids": Id, "NachbarIds": NachbarIds}) + + gefaehlleStrecken.append({"Id": Id, "NachbarIds": NachbarIds}) if bezeichner == "ILS 2.0 Kreisel": Id = row["TeileId"].strip() + planquadrat = row["Planquadrat"] + x, y = extract_coords(planquadrat) merkmale = parse_merkmale(row.get("Merkmale", "")) - drehung = merkmale.get("Drehung") - kreisel.append({"Id":Id, "drehung":drehung}) + drehung = merkmale.get("Drehrichtung") + rotation = merkmale.get("Drehung") + hight = float(merkmale.get("Höhe in m")) *1000 + kreisel.append({"Id":Id, "drehung":drehung, "höhe":hight,"x": x, "y": y, "rotation": rotation}) - bezeichner = row["Bezeichnung"].strip() - for gefaelleStrecke in gefaehlleStrecken: + for gefaelle in gefaehlleStrecken: + anweisungen = 0 + eintrag = {"Id": gefaelle["Id"]} for kreis in kreisel: - if kreis.get("Id") in gefaelleStrecke.get("NachbarIds") and anweisungen == 0: - richtung.append({"Id": gefaelleStrecke.get("Ids"), "Drehung": kreis.get("drehung") }) - anweisungen = 1 - elif kreis.get("Id") in gefaelleStrecke.get("NachbarIds") and anweisungen == 1: - richtung.update({"Drehung2" : kreis.get("drehung")}) - - return richtung + if kreis["Id"] in gefaelle["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") + 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") + break + gefaellestrecken_nachbarn.append(eintrag) + + return gefaellestrecken_nachbarn @@ -570,7 +660,7 @@ def main(csv_path: Path, lib_path: Path, cfg_path: Path, blocklib_dir = data_dir / "block_libraries" lib_docs = dict() - richtung = get_rotations_of_gefaellestrecke(csv_path) + gefaellestrecken_nachbarn = get_rotations_of_gefaellestrecke(csv_path) # 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') @@ -627,7 +717,7 @@ def main(csv_path: Path, lib_path: Path, cfg_path: Path, if func_name.startswith('handle_omniflo'): handler = globals().get('handle_omniflo') if handler: - handler(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, richtung, config) + handler(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, gefaellestrecken_nachbarn, config) else: msg = f"[WARN] Keine Routine für TeileArt '{teileart}'. Überspringe '{teileid}'." if logger: