removed test version started creating gefaellestrecke

This commit is contained in:
2025-09-29 12:39:29 +02:00
parent d92b060ab2
commit 008218ebc1
+145 -60
View File
@@ -11,6 +11,9 @@ import re
import argparse import argparse
import configparser import configparser
import ezdxf import ezdxf
from ezdxf import units
from ezdxf.entities import Line
from ezdxf.math import Matrix44
from pathlib import Path from pathlib import Path
import math import math
from utils import check_environment_var, setup_logger from utils import check_environment_var, setup_logger
@@ -157,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).""" """Transformiert Bildschirmkoordinaten (0,0 oben links) ins DXF-KoSy (0,0 unten links)."""
return x, y return x, y
def handle_ils_2_0_kreisel(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols): def handle_ils_2_0_kreisel(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, richtung,config):
abstand_m = merkmale.get( abstand_m = merkmale.get(
"Abstand (Kreiselachse A - Kreiselachse) in Meter", "20" "Abstand (Kreiselachse A - Kreiselachse) in Meter", "20"
).replace(",", ".") ).replace(",", ".")
@@ -278,77 +281,110 @@ def handle_standard(msp, blocknames, teileid, x, y, lib_doc, doc, verbose):
f"({x:.1f}, {y:.1f})") f"({x:.1f}, {y:.1f})")
def handle_ils_2_0_gefaellestrecke(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols): 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)] # blocks: [block1, block2], offsets: [(ox1, oy1), (ox2, oy2)]
# Länge der Strecke (in Meter, Standard 10) # Länge der Strecke (in Meter, Standard 10)
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
laenge_m = merkmale.get("Länge in Meter", "10").replace(",", ".") laenge_m = merkmale.get("Länge in Meter", "10").replace(",", ".")
try: try:
laenge = float(laenge_m) * 1000 # Meter → mm laenge = float(laenge_m) * 1000 # Meter → mm
except ValueError: except ValueError:
laenge = 10000 # Fallback 10m laenge = 10000 # Fallback 10m
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
# Drehung (Winkel in Grad, Standard 0) # dy = halbe_laenge * math.cos(0)
try: # start = (x , y + dy - asoffset,upper_hight)
winkel = float(merkmale.get("Drehung", 0)) # ende = (x , y - dy + esoffset,lower_hight)
except (ValueError, TypeError): # line = Line.new(dxfattribs={"start": start, "end": ende})
winkel = 0.0 # copy= line.copy()
winkel_rad = math.radians(winkel)
# Die Koordinaten (x, y) sind die Mitte der Strecke # copy.translate(-x,-y,-hight)
halbe_laenge = laenge / 2 # block.add_entity(copy)
dx = halbe_laenge * math.sin(winkel_rad) # a = "200000241_AS-Element_90_rechts"
dy = halbe_laenge * math.cos(winkel_rad) # import_block(a,lib_doc,doc)
start = (x + dx, y + dy,float(merkmale.get("Höhe oben") ) *1000) # b = "200000146_ES-Element_90_rechts"
ende = (x - dx, y - dy,float(merkmale.get("Höhe unten")) * 1000) # import_block(b,lib_doc,doc)
msp.add_line(start, ende) # 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()
# 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)
# 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:
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()
copy.translate(-x ,-y,-hight)
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.add_blockref(b, (ende[0]-x ,ende[1]-esoffset -y,ende[2]),)
msp.add_blockref(blockname,(x,y,hight),dxfattribs={"rotation": merkmale.get("Drehung")})
if verbose: if verbose:
print(f"[INFO] Gefällestrecke → {teileid} Linie von ({start[0]:.1f}, {start[1]:.1f}) nach ({ende[0]:.1f}, {ende[1]:.1f})") print(f"[INFO] Gefällestrecke → {teileid} Linie von ({start[0]:.1f}, {start[1]:.1f}) nach ({ende[0]:.1f}, {ende[1]:.1f})")
# Blöcke am Anfang und Ende der Strecke aus der CFG platzieren
if len(symbols) >= 2 and lib_doc is not None:
for i, sym in enumerate(symbols[:2]):
blockname = sym["name"]
offset = sym["offset"]
rotation = sym["rotation"]
pos = (start[0] + offset[0], start[1] + offset[1]
) if i == 0 else (ende[0] + offset[0], ende[1] + offset[1])
import_block(blockname, lib_doc, doc)
blockref_layer = get_layer(doc, lib_doc, blockname)
bref = msp.add_blockref(blockname, pos, dxfattribs={
"rotation": rotation,"layer": blockref_layer})
bref.add_auto_attribs({ATTR_TAG: teileid})
if verbose:
print(
f"[INFO] Block '{blockname}' an {'Startpunkt' if i == 0 else 'Endpunkt'} {pos} für {teileid}, rot={rotation}")
elif lib_doc is None:
print("[WARN] lib_doc nicht verfügbar, Blöcke werden nicht eingefügt.")
def handle_ils_2_0_kurve_angetrieben(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols):
center =x,y
winkel_deg = float(merkmale.get("Kurvenwinkel"))
richtung = merkmale.get("Kurvenrichtung")
if richtung.lower() == "links": def handle_omniflo(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, richtung,config):
end_angle = 180
else:
start_angle= 0
# Endwinkel je nach Richtung
if richtung.lower() == "links":
start_angle = end_angle- winkel_deg
elif richtung.lower() == "rechts":
end_angle = start_angle + winkel_deg
else:
raise ValueError("Unbekannte Kurvenrichtung: Muss 'links' oder 'rechts' sein")
msp.add_arc(
center=center,
radius=400,
start_angle=start_angle,
end_angle=end_angle
)
def handle_omniflo(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols):
""" """
Für Omniflo Gerade: zeichnet eine Linie (Mitte = Koordinate, Länge und Winkel aus Merkmale). 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. Für alle anderen Omniflo-Typen: Block mit SivasNummer an den Koordinaten.
@@ -465,15 +501,58 @@ def get_libfile_cfg(teileart, cfg_path):
return parser.get(section, "libfile", fallback=None) return parser.get(section, "libfile", fallback=None)
return None return None
def get_rotations_of_gefaellestrecke(csv_path:Path) -> dict:
gefaehlleStrecken = dict()
kreisel =dict()
richtung = dict()
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:
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()
gefaehlleStrecken.append({"Ids": Id, "NachbarIds": NachbarIds})
if bezeichner == "ILS 2.0 Kreisel":
Id = row["TeileId"].strip()
merkmale = parse_merkmale(row.get("Merkmale", ""))
drehung = merkmale.get("Drehung")
kreisel.append({"Id":Id, "drehung":drehung})
bezeichner = row["Bezeichnung"].strip()
for gefaelleStrecke in gefaehlleStrecken:
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
# --------------------------------------------------------- Hauptfunktion # --------------------------------------------------------- Hauptfunktion
def main(csv_path: Path, lib_path: Path, cfg_path: Path, def main(csv_path: Path, lib_path: Path, cfg_path: Path,
output_path: Path, verbose=False, logger=None): output_path: Path, verbose=False, logger=None):
# Bibliothek nur laden, wenn Datei existiert # Bibliothek nur laden, wenn Datei existiert
check_dxflibrary_path(lib_path, verbose, logger) check_dxflibrary_path(lib_path, verbose, logger)
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}"
# Neue Ziel­zeichnung (DXF R2018) # Neue Ziel­zeichnung (DXF R2018)
config =parser
doc = ezdxf.new(dxfversion="R2018") doc = ezdxf.new(dxfversion="R2018")
doc.units = units.M
doc.header['$INSUNITS'] = 4 # Millimeter doc.header['$INSUNITS'] = 4 # Millimeter
msp = doc.modelspace() msp = doc.modelspace()
@@ -491,6 +570,10 @@ def main(csv_path: Path, lib_path: Path, cfg_path: Path,
blocklib_dir = data_dir / "block_libraries" blocklib_dir = data_dir / "block_libraries"
lib_docs = dict() lib_docs = dict()
richtung = 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')
# Verarbeitung der Blöcke # Verarbeitung der Blöcke
with csv_path.open(newline="", encoding="utf-8") as fh: with csv_path.open(newline="", encoding="utf-8") as fh:
reader = csv.DictReader(fh, delimiter=';') reader = csv.DictReader(fh, delimiter=';')
@@ -502,6 +585,7 @@ def main(csv_path: Path, lib_path: Path, cfg_path: Path,
merkmale = parse_merkmale(row.get("Merkmale", "")) merkmale = parse_merkmale(row.get("Merkmale", ""))
merkmale["bezeichner"] = bezeichner merkmale["bezeichner"] = bezeichner
try: try:
x_screen, y_screen = extract_coords(planquadrat) x_screen, y_screen = extract_coords(planquadrat)
x, y = transform_coords(x_screen, y_screen, height) x, y = transform_coords(x_screen, y_screen, height)
@@ -543,7 +627,7 @@ def main(csv_path: Path, lib_path: Path, cfg_path: Path,
if func_name.startswith('handle_omniflo'): if func_name.startswith('handle_omniflo'):
handler = globals().get('handle_omniflo') handler = globals().get('handle_omniflo')
if handler: if handler:
handler(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols) handler(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, richtung, config)
else: else:
msg = f"[WARN] Keine Routine für TeileArt '{teileart}'. Überspringe '{teileid}'." msg = f"[WARN] Keine Routine für TeileArt '{teileart}'. Überspringe '{teileid}'."
if logger: if logger:
@@ -613,3 +697,4 @@ if __name__ == "__main__":
main(csv_path, default_lib_path, cfg_path, output_path, verbose=args.verbose, logger=logger) main(csv_path, default_lib_path, cfg_path, output_path, verbose=args.verbose, logger=logger)
logger.info("=== plant2dxf Verarbeitung abgeschlossen ===") logger.info("=== plant2dxf Verarbeitung abgeschlossen ===")