removed test version started creating gefaellestrecke
This commit is contained in:
+145
-60
@@ -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 10 m
|
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
|
||||||
|
|
||||||
# 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 Zielzeichnung (DXF R2018)
|
# Neue Zielzeichnung (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 ===")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user