32 KiB
plant2dxf - Dokumentation
⚠️ Wichtiger Hinweis
Zukünftige Anpassungen erforderlich:
Aufgrund möglicher Änderungen im CSV-Dateiformat von RuleDesigner müssen in Zukunft möglicherweise folgende Berechnungen und Logiken angepasst werden:
AS/ES-Element-Berechnungen
Die Logik zur Bestimmung und Platzierung von AS- und ES-Elementen bei Gefällestrecken und Vario-Förderern basiert auf dem aktuellen CSV-Format. Bei Änderungen der Datenstruktur oder der verfügbaren Informationen müssen folgende Methoden in as_es_methoden.py überprüft und angepasst werden:
erstellung_gefaelle_block_verbunden_an_einen(): Erstellt AS/ES-Elemente für Gefällestrecken, die mit einem Kreisel verbunden sindgefaellegerade_erstellung(): Erstellt AS/ES-Elemente für Gefällestrecken, die mit zwei Kreiseln verbunden sindam_kreisel_direct_verbunden(): Prüft, ob eine Gefällestrecke/Vario-Förderer direkt mit einem Kreisel verbunden ist (ohne Stahlband)
Höhenvergleiche für Kreisel-Logik
Die Höhenvergleiche zur Bestimmung der Verbindungsart zwischen Gefällestrecken/Vario-Förderern und Kreiseln (z.B. ob die Gefällestrecke mit dem höheren oder niedrigeren Teil des Kreisels verbunden ist) basieren auf den aktuellen CSV-Datenfeldern. Änderungen in der Struktur der Höheninformationen erfordern Anpassungen in:
Handler-Funktionen (lib/plant2dxf.py):
handle_ils_2_0_gefaellestrecke(): Haupt-Handler für Gefällestreckenhandle_ils_2_0_variofoerderer(): Haupt-Handler für Vario-Förderer
Gefällestrecke-Methoden (lib/Elemente/Gefaellestrecke.py):
rotation_mit_zwei_verbunden(): Berechnet Rotation bei Verbindung mit zwei Kreiseln (verwendet Höhenvergleiche)
Vario-Förderer-Methoden (lib/Elemente/VarioFoerderer.py):
vario_verbuden_am_kreisel(): Erstellt Gefällestrecken-Komponenten bei direkter Kreisel-Verbindung (verwendet Höhenvergleiche mit Kreiseln)
Betroffene Dateien:
lib/as_es_methoden.py: AS/ES-Element-Berechnungenlib/plant2dxf.py: Handler-Funktionen für Gefällestrecken und Vario-Fördererlib/Elemente/Gefaellestrecke.py: Höhenvergleiche und Verbindungslogiklib/Elemente/VarioFoerderer.py: Höhenvergleiche und Verbindungslogik
Übersicht
plant2dxf ist ein Python-Skript, das aus einer RuleDesigner-CSV-Datei DXF-Elemente erzeugt. Das Skript liest eine CSV-Datei mit Angaben über alle in einer Anlage enthaltenen Elemente und generiert daraus eine DXF-Datei der kompletten Anlage.
Hauptfunktionalität
Das Skript verarbeitet CSV-Dateien mit folgenden Informationen:
- TeileArt: Typ der Komponente (z.B. "ILS 2.0 Kreisel", "ILS 2.0 Gefällestrecke")
- TeileId: Eindeutige Identifikation des Elements
- Planquadrat: Koordinaten im Format
X:<Wert> Y:<Wert> - Merkmale: JSON-String mit spezifischen Eigenschaften des Elements
- NachbarIds: Kommagetrennte Liste von IDs benachbarter Elemente
Benötigte Dateien und Verzeichnisse
Umgebungsvariablen
Das Skript benötigt folgende Umgebungsvariablen (werden durch bin/setenv.bat gesetzt):
-
PROJECT_DATA: Verzeichnis für Bibliotheksdateien (DXF-Blockbibliotheken)
- Standard:
<PROJECT>/data - Enthält Unterverzeichnis
block_libraries/mit DXF-Bibliotheken
- Standard:
-
PROJECT_WORK: Arbeitsverzeichnis für CSV-Eingabedateien und DXF-Ausgabedateien
- Standard:
<PROJECT>/work
- Standard:
-
PROJECT_CFG: Verzeichnis für Konfigurationsdateien
- Standard:
<PROJECT>/cfg - Enthält:
allgemein.cfg,shapes.cfg
- Standard:
-
PROJECT_LOG: Verzeichnis für Log-Dateien
- Standard:
<PROJECT>/log
- Standard:
Konfigurationsdateien
1. cfg/allgemein.cfg
Allgemeine Konfigurationsdatei, die die Zuweisung von Block-Bibliotheken zu bestimmten Bauteil-Familien steuert.
Struktur:
[LOG]
log_level = INFO
log_format = %%(asctime)s - %%(levelname)s - %%(message)s
screen_format = %%(message)s
[ILS]
libfile = ils_lib.dxf
[Omniflo]
libfile = omniflo_lib.dxf
[BT]
libfile = ils_lib.dxf
[TEF]
libfile = omniflo_lib.dxf
Zweck:
- Definiert, welche DXF-Bibliotheksdatei für welche TeileArt verwendet wird
- Bibliotheksdateien werden aus
PROJECT_DATA/block_libraries/geladen - Falls keine Zuordnung gefunden wird, wird die Standard-Bibliothek (
blocks.dxf) verwendet
2. cfg/shapes.cfg
Definiert für jede TeileArt die zu verwendenden Blöcke aus der Bibliotheks-DXF und deren Eigenschaften.
Struktur:
[ILS 2.0 Kreisel]
items = SP8, AN8
offset_symb1 = 0,0
offset_symb2 = 0,0
rot_symb1 = 0.0
rot_symb2 = 0.0
[ILS 2.0 Gefällestrecke]
items = EE DS, AE DS
offset_symb1 = 0,-330
offset_symb2 = 0,1000
rot_symb1 = 0.0
rot_symb2 = 0.0
asoffset = 537.90
esoffset = 479.95
[ILS 2.0 Variofoerderer]
Umlenkstation = 500.0, 0.0, 0.0
Motorstation = 500.0, 0.0, 0.0
vario_abstand = 66.5
[Ils 2.0 core winkel]
winkel_boegen = 3
winkel_motor = 3.0
winkel_umlenk = 3.0
winkel_as = 3.0
winkel_es = 3.0
[Omniflo]
OFgeradesivas = 821106002
Tefgeradesivas = 0_B10030
OFfoerderer = 2
Parameter:
- [TeileArt]: Abschnittsname muss exakt dem Wert aus der CSV-Spalte
TeileArtentsprechen - items: Kommagetrennte Liste der Blocknamen aus der Bibliothek
- offset_symbX: Offset (x,y) für den X-ten Block relativ zur berechneten Position
- rot_symbX: Rotation (in Grad) für den X-ten Block
- asoffset/esoffset: Offsets für AS/ES-Elemente bei Gefällestrecken
- winkel_*: Winkel für verschiedene Komponenten (Bögen, Motor, Umlenkstation, AS/ES)
DXF-Bibliotheken
DXF-Bibliotheken enthalten die Blockdefinitionen für die verschiedenen Komponenten. Sie werden aus PROJECT_DATA/block_libraries/ geladen.
Bibliotheksdateien:
ils_lib.dxf: Blöcke für ILS 2.0 Komponentenomniflo_lib.dxf: Blöcke für Omniflo-Komponentenblocks.dxf: Standard-Bibliothek (Fallback)
Wichtige Blöcke:
SCAN: Scanner-BlockS-LP: Separator-BlockPinbereich: Pinbereich-Block für KreiselAN8,SP8: Standard-Blöcke für Kreisel200000241_AS-Element_90_rechts,200000217_AS-Element_90_links: AS-Elemente200000146_ES-Element_90_rechts,400102632_ES-Element_90_links: ES-Elemente- Verschiedene Omniflo-Blöcke (identifiziert über SivasNummer)
Unterstützte Elementtypen
1. ILS 2.0 Kreisel
Handler: handle_ils_2_0_kreisel()
Funktionalität:
- Erstellt einen Kreisel mit Scanner und Separatoren
- Positioniert Blöcke basierend auf Anzahl der Scanner/Separatoren
- Zeichnet Kreisel-Linien und Drehrichtung-Markierung
- Verwendet Blöcke aus
shapes.cfg(z.B. SP8, AN8)
Merkmale:
Abstand (Kreiselachse A - Kreiselachse) in Meter: Abstand zwischen den beiden KreiselachsenAnzahl der Separatoren: Anzahl der Separator-BlöckeAnzahl der Scanner: Anzahl der Scanner-BlöckeAnzahl der Rampen: Anzahl der RampenHöhe in m: Höhe des KreiselsDrehrichtung: UZS (Uhrzeigersinn) oder GUZS (Gegen-Uhrzeigersinn)
2. ILS 2.0 Gefällestrecke
Handler: handle_ils_2_0_gefaellestrecke()
Funktionalität:
- Erstellt eine Gefällestrecke zwischen verschiedenen Höhen
- Berücksichtigt Verbindungen zu Kreiseln, Kurven und anderen Elementen
- Fügt AS/ES-Elemente ein, wenn nötig
- Erstellt Blöcke dynamisch basierend auf Verbindungen
Merkmale:
Länge in Meter: Länge der GefällestreckeHöhe Anfang: Start-Höhe in MeternHöhe Ende: End-Höhe in MeternDrehung: Rotation der StreckeAnzahl der Zusatzseparatoren: Zusätzliche Separatoren
Besonderheiten:
- Unterscheidet zwischen Verbindung mit einem oder zwei Kreiseln
- Prüft, ob direkte Verbindung zum Kreisel (ohne Stahlband)
- Fügt Motor-/Umlenkstationen ein, wenn mit angetriebenen Kurven verbunden
- Erstellt AS/ES-Elemente basierend auf Drehrichtung der benachbarten Kreisel
3. ILS 2.0 VarioFoerderer
Handler: handle_ils_2_0_variofoerderer()
Funktionalität:
- Erstellt einen Vario-Förderer mit verschiedenen Konfigurationen
- Unterstützt Verbindungen zu Kreiseln, Eckrädern und anderen Vario-Förderern
- Berücksichtigt Motor- und Umlenkstationen
- Erstellt Gefälle-Komponenten innerhalb des Förderers
Merkmale:
Winkel: Winkel des FörderersFörderrichtung: Auf, Ab oder HorizontalMotorseite: links oder rechtsHöhe Anfang,Höhe Ende: Höhen der EndpunkteGefälle: Gefälle-Länge und -WinkelMotor vorhanden,Umlenk vorhanden: Boolean-Werte
Besonderheiten:
- Unterscheidet zwischen Verbindung mit einem oder zwei Kreiseln/Eckrädern
- Erstellt spezielle Blöcke für direkte Kreisel-Verbindungen
- Berücksichtigt horizontale Ausrichtung bei Eckrad-Verbindungen
- Fügt Gefällestrecken ein, wenn mit Kreiseln verbunden
4. ILS 2.0 Kurve angetrieben
Handler: handle_ils_2_0_kurve_angetrieben()
Funktionalität:
- Erstellt eine angetriebene Kurve (Förderer-Kurve)
- Verwendet Blocknamen basierend auf Kurvenrichtung, Winkel und Antrieb
Merkmale:
Kurvenrichtung: Links oder RechtsKurvenwinkel: Winkel der Kurve in GradAntrieb: TEF-Kurve oder ähnlichHöhe Anfang,Höhe Ende: Höhen der Endpunkte
5. ILS 2.0 Kurve (Gefälle-Kurve)
Handler: handle_ils_2_0_kurve()
Funktionalität:
- Erstellt eine Gefälle-Kurve
- Verwendet Blocknamen basierend auf Kurvenrichtung und Winkel
Merkmale:
Kurvenrichtung: Links oder RechtsKurvenwinkel: Winkel der Kurve in GradHöhe Anfang,Höhe Ende: Höhen der Endpunkte
6. ILS 2.0 Eckrad
Handler: handle_ils_2_0_eckrad()
Funktionalität:
- Erstellt ein Eckrad basierend auf Drehrichtung
- Verwendet unterschiedliche Blöcke für UZS/GUZS
Merkmale:
Drehrichtung: UZS oder GUZSHöhe: Höhe des Eckrads
7. BT Elemente (Beladung/Entladung)
Handler: handle_bt___beladung(), handle_bt___entladung()
Funktionalität:
- Erstellt BT-Elemente für Beladung oder Entladung
- Verwendet Standard-Block "AN8"
Merkmale:
Höhe: Höhe des ElementsDrehung: Rotation
8. Omniflo
Handler: handle_omniflo()
Funktionalität:
- Erstellt Omniflo-Komponenten basierend auf SivasNummer
- Unterstützt Geraden, Förderer und spezielle Blöcke
- Verwendet Blocknamen direkt aus der SivasNummer
Merkmale:
SivasNummer: Identifikation des Omniflo-BlocksHöhe: Höhe des ElementsDrehung: RotationLänge: Länge (für Geraden)
Besonderheiten:
- Spezielle Behandlung für Geraden (SivasNummer aus Config)
- Erstellt Linien für Geraden statt Blöcke
- Unterstützt Förderer-Komponenten
CSV-Dateiformat
Die CSV-Datei muss folgende Spalten enthalten (Semikolon-getrennt):
Elementnummer;TeileArt;TeileId;NachbarIds;Bezeichnung;Planquadrat;Merkmale
Spalten:
- Elementnummer: Fortlaufende Nummer
- TeileArt: Typ der Komponente (muss exakt mit Config übereinstimmen)
- TeileId: Eindeutige ID (z.B. "shape_...")
- NachbarIds: Kommagetrennte Liste von IDs benachbarter Elemente
- Bezeichnung: Beschreibung des Elements
- Planquadrat: Koordinaten im Format
X:<Wert> Y:<Wert>(in mm) - Merkmale: JSON-String mit spezifischen Eigenschaften
Beispiel:
1;"ILS 2.0 Kreisel";"shape_f81e5c4b-a976-a3c0-3304-d2b30da1ab29";"shape_d76e250a-0a46-f6d0-df52-943ab572cc63";"Kreisel:1";"X:9174.15 Y:12039.11";{"Abstand (Kreiselachse A - Kreiselachse) in Meter":"20.265","Anzahl der Separatoren":"2","Anzahl der Scanner":"0","Höhe in m":"2"}
Verwendung
Kommandozeilen-Syntax
python plant2dxf.py -f <csv-datei> [Optionen]
Optionen:
-f, --file: CSV-Datei (Pfad oder Dateiname im WORK-Verzeichnis) [erforderlich]-c, --config: Pfad zur shapes.cfg (Standard:PROJECT_CFG/shapes.cfg)-l, --lib: Pfad zur DXF-Bibliothek (Standard:PROJECT_DATA/blocks.dxf)-o, --output: Ausgabe-DXF-Datei (Standard:<csv-name>.dxfim WORK-Verzeichnis)-v, --verbose: Ausführliche Ausgaben
Beispiele:
# Einfache Verwendung
python plant2dxf.py -f anlage.csv
# Mit expliziten Pfaden
python plant2dxf.py -f anlage.csv -c cfg/shapes.cfg -l data/blocks.dxf -o output.dxf
# Mit verbose-Ausgabe
python plant2dxf.py -f anlage.csv -v
Batch-Datei (Windows)
Verwende bin/plant2dxf.bat für einfache Ausführung:
plant2dxf.bat <csv-datei>
Verarbeitungslogik
1. Initialisierung
- Laden der Konfigurationsdateien (
shapes.cfg,allgemein.cfg) - Erstellen einer neuen DXF-Datei (DXF R2018, Einheit: Millimeter)
- Laden der Block-Bibliotheken (mit Caching)
2. CSV-Verarbeitung
Für jede Zeile in der CSV-Datei:
-
Parsen der CSV-Zeile:
- Extraktion von TeileArt, TeileId, Koordinaten, Merkmalen
- Parsen des Planquadrats zu X/Y-Koordinaten
- Parsen der Merkmale (JSON)
-
Nachbar-Informationen:
- Analyse der NachbarIds
- Bestimmung der Verbindungen zu Kreiseln, Kurven, Eckrädern
- Berechnung von Drehrichtungen, Höhen, Abständen
-
Bibliothekszuordnung:
- Bestimmung der Bibliotheksdatei aus
allgemein.cfg - Laden der Bibliothek (mit Cache)
- Bestimmung der Bibliotheksdatei aus
-
Handler-Aufruf:
- Normalisierung des TeileArt-Namens zu Funktionsname
- Aufruf der entsprechenden
handle_*-Funktion - Erstellung der DXF-Elemente
3. Element-Erstellung
Jeder Handler:
- Erstellt Objekte aus den Element-Klassen (
Kreisel,Gefaellestrecke, etc.) - Analysiert Verbindungen zu Nachbarn
- Erstellt dynamische Blöcke basierend auf Konfiguration
- Fügt Blöcke, Linien und andere DXF-Entitäten ein
- Setzt Attribute (z.B. TeileId)
4. Speicherung
- Speicherung der DXF-Datei im angegebenen Ausgabepfad
- Logging der Verarbeitung
Wichtige Module und Klassen
Element-Klassen (lib/Elemente/)
- Kreisel: Repräsentiert einen Kreisel mit allen Eigenschaften
- Gefaellestrecke: Repräsentiert eine Gefällestrecke
- VarioFoerderer: Repräsentiert einen Vario-Förderer
- Angetriebene_Kurve: Repräsentiert eine angetriebene Kurve
- Eckrad: Repräsentiert ein Eckrad
- Bt_element: Repräsentiert BT-Elemente
- Omniflo: Repräsentiert Omniflo-Komponenten
Hilfsmodule
- arbeiten_mit_csv.py: CSV-Parsing, Koordinaten-Extraktion, Nachbar-Analyse
- block_methoden.py: Block-Import, Rotation, Layer-Verwaltung
- as_es_methoden.py: AS/ES-Element-Erstellung, Höhen-Vertauschung
- utils.py: Umgebungsvariablen, Logger-Setup
Wichtige ezdxf-Methoden
Das Skript verwendet verschiedene Methoden der ezdxf-Bibliothek zur Erstellung und Manipulation von DXF-Elementen. Die wichtigsten Methoden sind:
1. Block-Referenz in Block einfügen
block.add_blockref(blockname, (x, y, z), dxfattribs={"rotation": rotation, "layer": layer, "color": color})
Beschreibung: Fügt eine Block-Referenz (INSERT) in einen bestehenden Block ein.
Parameter:
blockname(str): Name des Blocks, der eingefügt werden soll(x, y, z)(tuple): Koordinaten der Einfügeposition (3D-Tupel)dxfattribs(dict): Dictionary mit DXF-Attributen:rotation(float): Rotationswinkel in Gradlayer(str): Layer-Namecolor(int): Farbe (optional)
Verwendung: Wird verwendet, um Blöcke innerhalb von anderen Blöcken zu platzieren (z.B. Motorstationen in Gefällestrecken-Blöcken).
Beispiel:
block.add_blockref("Vario_Motorstation_500mm", (0, 250, 0), dxfattribs={"rotation": 270, "layer": "VARIO"})
2. Block-Referenz ins Modelspace einfügen
msp.add_blockref(blockname, (x, y, z), dxfattribs={"rotation": rotation, "layer": layer, "color": color})
Beschreibung: Fügt eine Block-Referenz direkt in den Modelspace (die Hauptzeichnung) ein.
Parameter:
blockname(str): Name des Blocks, der eingefügt werden soll(x, y, z)(tuple): Koordinaten der Einfügeposition (3D-Tupel)dxfattribs(dict): Dictionary mit DXF-Attributen (siehe oben)
Verwendung: Wird verwendet, um fertige Blöcke in die Zeichnung zu platzieren. Dies ist der häufigste Weg, um Elemente in die DXF-Datei einzufügen.
Beispiel:
msp.add_blockref("ILS_2.0_Gefaellestrecke_8200_2000_UZS_higher",
(x, y, hoehe_gefaelle),
dxfattribs={"rotation": rotation, "layer": "6-SP"})
3. Neuen Block erstellen
block = doc.blocks.new(name=blockname, base_point=(0, 0, 0))
Beschreibung: Erstellt einen neuen Block im DXF-Dokument.
Parameter:
name(str): Name des neuen Blocks (muss eindeutig sein)base_point(tuple): Basis-Punkt des Blocks (meist (0, 0, 0))
Rückgabewert: Block-Objekt, das verwendet werden kann, um Entitäten hinzuzufügen
Wichtiger Hinweis: Ein Block mit demselben Namen kann nur einmal erstellt werden. Vor der Erstellung sollte geprüft werden:
if blockname not in doc.blocks:
block = doc.blocks.new(name=blockname, base_point=(0, 0, 0))
Verwendung: Wird verwendet, um dynamische Blöcke zu erstellen, die aus mehreren Komponenten bestehen (z.B. Gefällestrecken mit Motorstationen, Vario-Förderer mit verschiedenen Konfigurationen).
Beispiel:
blockname = f"Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaelle}_{hat_motor_0}_{hat_umlenk_0}"
if blockname not in doc.blocks:
block = doc.blocks.new(name=blockname, base_point=(0, 0, 0))
# Füge Komponenten zum Block hinzu
block.add_blockref("Vario_Motorstation_500mm", (0, 0, 0))
line = Line.new(dxfattribs={"start": start, "end": ende})
line.translate(-x, -y, -hoehe_gefaelle)
block.add_entity(line)
4. DXF-Objekte aus Modelspace abfragen
entities = msp.query("INSERT")
Beschreibung: Holt alle spezifischen DXF-Objekte vom Modelspace.
Parameter:
"INSERT"(str): DXF-Typ des Objekts (z.B. "INSERT" für Block-Referenzen, "LINE" für Linien, "CIRCLE" für Kreise)
Rückgabewert: Liste von DXF-Entitäten des angegebenen Typs
Verwendung: Wird verwendet, um bestimmte Objekte aus der Zeichnung zu finden oder zu analysieren. Meistens wird dies für INSERT-Objekte (Block-Referenzen) verwendet.
Beispiel:
# Alle Block-Referenzen im Modelspace finden
inserts = msp.query("INSERT")
for insert in inserts:
print(f"Block: {insert.dxf.name} an Position {insert.dxf.insert}")
Weitere DXF-Typen:
"LINE": Linien"CIRCLE": Kreise"ARC": Bögen"TEXT": Text"ATTDEF": Attribut-Definitionen"INSERT": Block-Referenzen
5. Weitere wichtige ezdxf-Methoden
Linie erstellen und hinzufügen
# Linie direkt im Modelspace
line = msp.add_line(start=(x1, y1, z1), end=(x2, y2, z2))
line.dxf.layer = "6-SP"
# Linie in Block erstellen
line = Line.new(dxfattribs={"start": (x1, y1, z1), "end": (x2, y2, z2)})
line.translate(-x, -y, -z) # Relativ zum Block-Ursprung verschieben
block.add_entity(line)
Layer erstellen
if "LAYER_NAME" not in doc.layers:
doc.layers.add(name="LAYER_NAME", color=7)
Block-Attribute hinzufügen
bref = msp.add_blockref(blockname, (x, y, z))
bref.add_attrib(tag="NAME", text="Bezeichnung", insert=(x, y))
bref.add_auto_attribs({ATTR_TAG: teileid}) # Automatische Attribute aus Block-Definition
Entität transformieren
entity.translate(dx, dy, dz) # Verschieben
entity.rotate_z(angle) # Rotation um Z-Achse
entity.scale(factor) # Skalierung
Konstante Parameter
- ATTR_TAG:
"TeileId"- Attributtag im Block - RADIUS:
400- Radius der Kreiselkreise (in mm)
Layer-Verwaltung
Das Skript erstellt automatisch folgende Layer:
- VARIO: Für Vario-Förderer (Farbe: 3)
- 6-SP: Für Gefällestrecken (Farbe: 7)
- Weitere Layer werden aus den Bibliotheks-Blöcken übernommen
Fehlerbehandlung
- Fehlende Umgebungsvariablen führen zum Programmabbruch
- Fehlende Bibliotheksdateien werden geloggt, Verarbeitung wird fortgesetzt
- Fehlerhafte CSV-Zeilen werden übersprungen (mit Warnung)
- Fehlende Handler für TeileArt werden geloggt, Element wird übersprungen
Logging
- Log-Dateien werden in
PROJECT_LOG/gespeichert - Format:
plant2dxf_YYYYMMDD_HHMMSS.log - Logging erfolgt sowohl in Datei als auch auf Konsole
- Format:
%(asctime)s - %(levelname)s - %(message)s
Detaillierte Funktionsbeschreibungen
NachbarId-Entnahme und -Analyse
Die Funktion get_nachbar_information() in arbeiten_mit_csv.py analysiert die CSV-Datei und erstellt ein Dictionary mit allen Nachbar-Informationen für Gefällestrecken und Vario-Förderer.
Ablauf der Nachbar-Analyse
-
Erste Durchlauf - Sammeln aller Elemente:
- Gefällestrecken: Speichert ID und NachbarIds
- Kreisel: Erstellt Kreisel-Objekte und speichert:
drehung: Drehrichtung (UZS/GUZS)höhe: Höhe des Kreiselsx,y: Koordinatenrotation: Rotationswinkelabstand: Abstand zwischen Kreiselachsen (in Metern)
- Vario-Förderer: Speichert ID, NachbarIds, Winkel, Höhen, Förderrichtung, Koordinaten
- Angetriebene Kurven: Speichert ID, Höhen, Kurvenrichtung, TEF-Kurve-Status, Winkel, Koordinaten
- Eckräder: Speichert ID, Höhe, Koordinaten
-
Zweiter Durchlauf - Zuordnung der Nachbarn: Für jede Gefällestrecke oder Vario-Förderer:
a) Angetriebene Kurven (TEF-Kurven):
- Prüft, ob Kurven-IDs in den NachbarIds enthalten sind
- Speichert für erste Kurve (
voerder_anweisung == 0):X_angetrieben,Y_angetrieben: Koordinatenvario_hoehe_0,vario_hoehe_1: Höhen der KurveKurvenrichtung: Links oder RechtsTefkurve: Antriebsart (außen/innen)Kurvenwinkel: Winkel der Kurve
- Speichert für zweite Kurve (
voerder_anweisung == 1):- Gleiche Felder mit Suffix
_1
- Gleiche Felder mit Suffix
b) Eckräder:
- Prüft, ob Eckrad-IDs in den NachbarIds enthalten sind
- Speichert für erstes Eckrad (
eckrad_anweisung == 0):Eckrad_x,Eckrad_y: KoordinatenEckrad_höhe: Höhe des Eckrads
- Speichert für zweites Eckrad (
eckrad_anweisung == 1):- Gleiche Felder mit Suffix
_1
- Gleiche Felder mit Suffix
c) Kreisel:
- Prüft, ob Kreisel-IDs in den NachbarIds enthalten sind
- Speichert für ersten Kreisel (
anweisungen == 0):Drehung0: Drehrichtung (UZS/GUZS)Hoehe0: Höhe des Kreiselsx0,y0: Koordinatenrotation0: Rotationswinkelabstand0: Abstand zwischen Kreiselachsen (in Metern)
- Speichert für zweiten Kreisel (
anweisungen == 1):- Gleiche Felder mit Suffix
1statt0
- Gleiche Felder mit Suffix
d) Vario-Förderer (nur für Vario-Förderer):
- Prüft, ob andere Vario-Förderer in den NachbarIds enthalten sind
- Speichert für ersten Vario-Förderer (
geraden_anweisung == 0):X_foerderer,Y_foerderer: KoordinatenWinkel: Winkel des Förderersh0,h1: HöhenFoerderrichtung: Auf/Ab/Horizontal
- Speichert für zweiten Vario-Förderer (
geraden_anweisung == 1):- Gleiche Felder mit Suffix
_2
- Gleiche Felder mit Suffix
Verwendung der Nachbar-Informationen
Die Nachbar-Informationen werden verwendet für:
- Gefällestrecken: Bestimmung der AS/ES-Elemente, Motor/Umlenkstationen, direkte Kreisel-Verbindungen
- Vario-Förderer: Bestimmung der Verbindungsart, Gefälle-Komponenten, Offset-Berechnungen
Gefällestrecke mit Motor/Umlenkstation - Detaillierte Erstellung
Die Erstellung einer Gefällestrecke mit Motor- oder Umlenkstation erfolgt in mehreren Schritten:
1. Prüfung auf Motor/Umlenkstation-Bedarf
Die Methode hat_motor_umlenk_station() prüft, ob eine Gefällestrecke eine Motor- oder Umlenkstation benötigt:
Logik:
- Prüft, ob
Kurvenrichtungin den Nachbar-Informationen vorhanden ist (d.h. verbunden mit angetriebener Kurve) - Bestimmt
tefkurve_0basierend auf Kurvenrichtung und Antriebsart:kurvenrichtung == "links"undTefkurve == "außen"→tefkurve_0 = "rechts"kurvenrichtung == "rechts"undTefkurve == "innen"→tefkurve_0 = "rechts"- Sonst →
tefkurve_0 = "links"
Höhen-basierte Bestimmung:
- Wenn
upper_hoehe_gefaelle > lower_hoehe_gefaelle:- Wenn
vario_hoehe_0odervario_hoehe_1 == upper_hoehe_gefaelle→hat_motor_0 = True - Sonst →
hat_umlenk_0 = True
- Wenn
- Wenn
upper_hoehe_gefaelle < lower_hoehe_gefaelle:- Wenn
vario_hoehe_0odervario_hoehe_1 == lower_hoehe_gefaelle→hat_motor_0 = True - Sonst →
hat_umlenk_0 = True
- Wenn
Rotations-basierte Bestimmung (bei gleicher Höhe):
- Wenn beide Höhen gleich sind, wird die Position relativ zur Kurve geprüft
- Basierend auf Rotation und Koordinaten wird entschieden:
hat_umlenk_0 = True+umlenk_gerade = True(wenn bestimmte Bedingungen erfüllt)- Oder
hat_motor_0 = True+motor_gerade = True
2. Erstellung des Blocks mit Motor/Umlenkstation
Die Methode ein_motor_oder_eine_umlenk() erstellt die Motor- oder Umlenkstation im Block:
Schritte:
-
Import der Vario-Bögen:
Vario_Bogen_auf_3°: Bogen für Aufwärts-BewegungVario_Bogen_ab_3°: Bogen für Abwärts-Bewegung- Erstellung der Links-Versionen durch
turn_two_blocks_left()
-
Auslesen der Delta-Werte:
DELTA_SP_0,DELTA_SP_1: Delta-Werte für StartpunktDELTA_VP_0,DELTA_VP_1: Delta-Werte für Verbindungspunkt- Negative Werte werden in positive umgewandelt
-
Motor-Station einfügen (
hat_motor_0 == True):- Wenn
tefkurve_0 == "links":- Wenn
motor_gerade == False:- Fügt
Vario_Bogen_ab_linksein (Rotation 270°) - Berechnet neuen Startpunkt basierend auf Delta-Werten
- Fügt
blockname_motor_linksein (250mm Offset) - Verschiebt Startpunkt um 500mm * cos(3°) und sin(3°)
- Fügt
- Wenn
motor_gerade == True:- Fügt
Vario_Motorstation_500mm_linksdirekt ein - Verschiebt Startpunkt um 500mm
- Fügt
- Wenn
- Wenn
tefkurve_0 == "rechts":- Gleiche Logik mit rechts-Versionen der Blöcke
- Wenn
-
Umlenk-Station einfügen (
hat_umlenk_0 == True):- Wenn
tefkurve_0 == "links":- Wenn
umlenk_gerade == False:- Fügt
Vario_Bogen_aufein (Rotation 90°) - Berechnet neuen Endpunkt basierend auf Delta-Werten
- Fügt
blockname_umlenk_linksein (250mm Offset) - Verschiebt Endpunkt um 500mm * cos(3°) und sin(3°)
- Fügt
- Wenn
umlenk_gerade == True:- Fügt
Vario_Umlenkstation_500mm_linksdirekt ein - Verschiebt Endpunkt um 500mm
- Fügt
- Wenn
- Wenn
tefkurve_0 == "rechts":- Gleiche Logik mit rechts-Versionen der Blöcke
- Wenn
-
Rückgabe:
- Gibt modifizierte
startundendeKoordinaten zurück
- Gibt modifizierte
3. Blockname-Generierung
Der Blockname wird dynamisch generiert:
Ils_2.0_Gefaellestrecke_{laenge}_{hoehe_gefaelle}_{hat_umlenk_0}_{hat_motor_0}_{tefkurve_0}_{umlenk_gerade}_{motor_gerade}
4. Block-Erstellung
- Prüft, ob Block bereits existiert (Caching)
- Erstellt neuen Block mit Basis-Punkt (0,0,0)
- Ruft
ein_motor_oder_eine_umlenk()auf, um Motor/Umlenkstation einzufügen - Erstellt Linie zwischen modifiziertem Start- und Endpunkt
- Verschiebt Linie relativ zum Block-Ursprung
- Fügt Block-Referenz in Modelspace ein
Vario-Förderer ohne Verbindung - Detaillierte Erstellung
Wenn ein Vario-Förderer nicht mit einem Kreisel oder Eckrad verbunden ist, wird der einfachste Fall behandelt:
1. Vorbereitung
halbe_laenge = laenge / 2
dy = halbe_laenge * math.cos(0) # dy = halbe_laenge (da cos(0) = 1)
2. Blockname-Generierung
Rechts-Version:
Vario_Foerderer_{winkel}_{voerder_richtung}_{laenge}_{hoehe_vario}_rechts_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}
Links-Version:
Vario_Foerderer_{winkel}_{voerder_richtung}_{laenge}_{hoehe_vario}_links_{motor_vorhanden}_{umlenk_vorhanden}_{gefaelle}_{gefahellewinkel}
Parameter:
winkel: Winkel des Förderers (z.B. 3, 6, 9)voerder_richtung: Auf, Ab oder Horizontallaenge: Länge in mmhoehe_vario: Mittlere Höhe ((h0 + h1) / 2)motor_vorhanden: True/Falseumlenk_vorhanden: True/Falsegefaelle: Länge der Gefällestrecke (falls vorhanden)gefahellewinkel: Winkel der Gefällestrecke (falls vorhanden)
3. Block-Erstellung
-
Prüfung auf existierenden Block:
- Wenn Block bereits existiert, wird nur Block-Referenz eingefügt
- Auswahl zwischen Links- und Rechts-Version basierend auf
Motorseite
-
Neuer Block wird erstellt:
block = doc.blocks.new(blockname, base_point=(0,0,0)) -
Start- und Endpunkt berechnen:
start = (x, y + dy, upper_hoehe_vario) ende = (x, y - dy, lower_hoehe_vario)- Startpunkt: Mitte + halbe Länge in Y-Richtung, obere Höhe
- Endpunkt: Mitte - halbe Länge in Y-Richtung, untere Höhe
-
Vario-Erstellung aufrufen:
VarioFoerderer.VarioFoerderer.vario_erstellung( foerderer, doc, lib_doc, config, block, block_name_links, start, ende, voerder_richtung, winkel_VP_offset_vorne, # None, da keine Verbindung winkel_VP_offset_hinten # None, da keine Verbindung )
4. Vario-Erstellung (vario_erstellung())
Schritte:
-
Konfiguration auslesen:
winkel_motor: Winkel für Motorstation (aus Config, z.B. 3.0°)winkel_umlenk: Winkel für Umlenkstation (aus Config, z.B. 3.0°)umlenk_laenge: Länge der Umlenkstation (aus Config, z.B. 500.0mm)motor_laenge: Länge der Motorstation (aus Config, z.B. 500.0mm)vario_abstand: Abstand zwischen Vario-Komponenten (aus Config, z.B. 66.5mm)
-
Offset-Berechnung:
motor_offset_x = umlenk_laenge[0] * math.cos(math.radians(winkel_motor)) motor_offset_z = umlenk_laenge[0] * math.sin(math.radians(winkel_motor)) umlenk_offset_x = motor_laenge[0] * math.cos(math.radians(winkel_umlenk)) umlenk_offset_z = motor_laenge[0] * math.sin(math.radians(winkel_umlenk)) -
Gefälle-Länge anpassen:
- Wenn Motor vorhanden:
gefaelle = gefaelle - motor_offset_x - Wenn Umlenk vorhanden:
gefaelle = gefaelle - umlenk_offset_x
- Wenn Motor vorhanden:
-
Förderrichtung "Auf" oder "Horizontal":
- Erstellt Vario-Komponenten von Start zu Ende
- Fügt Motorstation am Start ein (falls vorhanden)
- Fügt Gefälle-Komponenten ein (falls vorhanden)
- Fügt Umlenkstation am Ende ein (falls vorhanden)
-
Förderrichtung "Ab":
- Erstellt Vario-Komponenten von Ende zu Start
- Fügt Umlenkstation am Ende ein (falls vorhanden)
- Fügt Gefälle-Komponenten ein (falls vorhanden)
- Fügt Motorstation am Start ein (falls vorhanden)
-
Links-Version erstellen:
- Erstellt gespiegelte Version des Blocks für Links-Motorseite
- Verwendet
turn_two_blocks_left()für Spiegelung
5. Block-Referenz einfügen
Basierend auf Motorseite aus Merkmalen:
Motorseite == "links"→ Fügtblock_name_linkseinMotorseite == "rechts"→ Fügtblocknameein
Position: (x, y, hoehe_vario)
Rotation: rotation aus Merkmalen
Erweiterbarkeit
Neue TeileArt hinzufügen
-
Config hinzufügen (
shapes.cfg):[Neue TeileArt] items = Block1, Block2 offset_symb1 = 0,0 rot_symb1 = 0.0 -
Handler-Funktion erstellen (
plant2dxf.py):def handle_neue_teileart(msp, teileid, merkmale, x, y, doc, lib_doc, verbose, symbols, strecken_nachbarn, config, config_allgemein): """Erstellt eine neue TeileArt in der neuen Dxf""" # Implementierung -
Bibliothekszuordnung (
allgemein.cfg):[Neue TeileArt] libfile = bibliothek.dxf -
Element-Klasse (optional,
lib/Elemente/):- Falls komplexe Logik benötigt wird, eigene Klasse erstellen
Abhängigkeiten
Siehe lib/requirements.txt:
ezdxf==1.4.1: DXF-Bibliotheksvg.path==7.0: SVG-Pfad-Verarbeitungpydantic>=2.0.0: Datenvalidierung
Bekannte Einschränkungen
- CSV muss UTF-8 kodiert sein
- Koordinaten müssen im Format
X:<Wert> Y:<Wert>vorliegen - Bibliotheksdateien müssen im DXF-Format vorliegen
- Blocknamen müssen exakt mit Bibliothek übereinstimmen