Integration der Funktionalität des Python Skripts in ein Lisp Skript, um den Umweg über DXF zu vermeiden und direkt in der Zeichnung arbeiten zu können

This commit is contained in:
2026-05-07 12:44:12 +02:00
parent e45d1bca9d
commit 690938157f
14 changed files with 1005533 additions and 136 deletions
+17 -136
View File
@@ -1,145 +1,26 @@
# DRT-Verbindungszähler - DXF-Analyse-Tool # Verbindungsanalyse für DRT-Gerüst
Ein Python-basiertes Werkzeug zur automatischen Erkennung und Markierung von Schnittpunkten zwischen Linien in DXF-Dateien. Dieses Projekt analysiert Liniennetzwerke auf spezifizierten Layern in DWG/DXF-Zeichnungen. Damit lassen sich in der Angebotsphase die Anzahl und Arten der notwendigen Gerüstverbinder einfach und schnell aus einer vorhandenen Zeichnung ableiten.
Verbindungspunkte werden klassifiziert in:
## Überblick - Kreuzungen
- T-Verbindungen
- Eckverbindungen
Dieses Projekt analysiert DXF-Dateien und identifiziert Verbindungs- bzw. Schnittpunkte zwischen Linien auf verschiedenen Layern. Die gefundenen Schnittpunkte werden mit Kreisen markiert und in einer separaten DXF-Datei sowie einem Textbericht ausgegeben. ## Implementierungen
## Projektstruktur ### Python-Version
```text - Offline Analyse
verbindungszaehler/ - Batch-Verarbeitung von DXF-Dateien
├── verbindungszaehler.bat # Hauptskript zum Starten der Analyse - Export von Ergebnis-DXFs + Reports
├── config/
│ └── config.cfg # Standardkonfiguration
├── scripts/
│ └── setenv.bat # Umgebungsvariablen und Verzeichnisstruktur
├── src/
│ └── lib/
│ ├── analyze.py # Python-Analyseskript
│ └── dxf_analyzer.py # Kernlogik
├── input/ # Eingabeverzeichnis für DXF-Dateien
└── output/ # Ausgabeverzeichnis für Ergebnisse
```
## Voraussetzungen ### LISP-Version (BricsCAD / AutoCAD)
- Windows-Betriebssystem - Direkte Analyse in BricsCAD durch Aufruf des Makros
- Python 3.x installiert und im PATH verfügbar - Keine DXF-Exporte notwendig
- Python-Bibliothek für DXF-Verarbeitung `ezdxf` - Visualisierung der Verbindungen zur Sichtkontrolle direkt in der Zeichnung
- Modul `dxf_analyzer.py` mit der Klasse `IntersectionAnalyzer`
## Installation ## Gemeinsames Ziel
1. Projekt in ein beliebiges Verzeichnis entpacken Beide Implementierungen nutzen dieselbe geometrische Logik zur Klassifikation von Linienverbindungen.
2. Sicherstellen, dass Python installiert ist
3. Benötigte Python-Pakete installieren (z.B. `pip install ezdxf`)
4. DXF-Dateien im `input/`-Verzeichnis ablegen
## Verwendung
### Methode 1: Alle Dateien im Input-Verzeichnis analysieren
Doppelklick auf `verbindungszaehler.bat` oder per Kommandozeile:
```batch
verbindungszaehler.bat
```
Alle DXF-Dateien im `input/`-Verzeichnis werden automatisch mit den Einstellungen aus `config.cfg` analysiert.
### Methode 2: Einzelne Datei per Drag & Drop
Ziehen Sie eine DXF-Datei direkt auf die `verbindungszaehler.bat` und lassen Sie sie los. Die Datei wird sofort mit den Einstellungen aus `config/config.cfg` analysiert.
### Methode 3: Einzelne Datei per Kommandozeile
```batch
verbindungszaehler.bat "C:\Pfad\zur\datei.dxf"
```
## Konfiguration
### config.cfg
Die Datei `config.example.cfg` enthält alle Einstellungen für die Analyse. Für individuelle Parameter muss eine Kopie von `config.example.cfg` erstellt und in `config.cfg` umbenannt werden. Diese dient nun als Konfigurationsdatei des Projekts.
Passen Sie diese Werte in `config.cfg` nach Bedarf an:
```cfg
LAYERS=D-1,D-5
TOLERANCE=0.06
MARK_RADIUS=150
```
**Parameter-Erklärung:**
- **LAYERS**: Kommagetrennte Liste der zu analysierenden Layer (z.B. "D-1,D-5,D-3")
- **TOLERANCE**: Maximaler Abstand in DXF-Einheiten, bei dem zwei Punkte als identisch gelten (für ungenaue Zeichnungen)
- **MARK_RADIUS**: Radius der Kreise in DXF-Einheiten, die Schnittpunkte markieren
**Hinweis:** Nach Änderungen in `config.cfg` werden die neuen Werte bei der nächsten Ausführung automatisch verwendet.
## Ausgabe
Das Tool erzeugt für jede analysierte DXF-Datei zwei Dateien im `output/`-Verzeichnis:
1. **[Dateiname]_markiert_[Datum]_[Zeit].dxf**
DXF-Datei mit eingezeichneten Kreisen an allen gefundenen Schnittpunkten
2. **[Dateiname]_analyse_[Datum]_[Zeit].txt**
Textbericht mit Details zu den gefundenen Verbindungen (Koordinaten, Anzahl, etc.)
**Beispiel:**
```text
zeichnung_markiert_20241202_14-30-25.dxf
zeichnung_analyse_20241202_14-30-25.txt
```
## Funktionsweise
1. **setenv.bat** richtet die Verzeichnisstruktur ein und lädt die Konfigurationswerte aus `config.cfg` im `config/`-Ordner
2. **verbindungszaehler.bat** verarbeitet die angegebene Datei (oder alle Dateien im Input-Ordner) und ruft das Python-Skript auf
3. **analyze.py** lädt die DXF-Datei und übergibt sie zusammen mit den Konfigurationsparametern an den `IntersectionAnalyzer`
4. Der Analyzer findet Schnittpunkte zwischen Linien auf den angegebenen Layern innerhalb der definierten Toleranz
5. Gefundene Schnittpunkte werden mit Kreisen (Radius aus `MARK_RADIUS`) markiert
6. Ergebnisse werden als neue DXF-Datei und Textbericht gespeichert
## Workflow-Beispiel
1. DXF-Dateien in den `input/`-Ordner kopieren
2. `config.cfg` im `config/`-Ordner öffnen und gewünschte Layer-Namen, Toleranz und Markierungsradius eintragen
3. `verbindungszaehler.bat` per Doppelklick starten **oder** eine einzelne DXF-Datei auf die Batch-Datei ziehen
4. Ergebnisse im `output/`-Ordner überprüfen: **Bevor die Anzahl der Verbindungen weiter verwendet wird, sind die markierten Punkte im Ausgabelayout zwingend auf Fehler zu überprüfen!**
## Hinweise
- Stellen Sie sicher, dass die Layer-Namen in `config.cfg` exakt mit denen in der DXF-Datei übereinstimmen (Groß-/Kleinschreibung beachten)
- Bei sehr großen Dateien kann die Analyse einige Zeit in Anspruch nehmen
- Die Toleranz sollte an die Genauigkeit Ihrer Zeichnungen angepasst werden (typische Werte: 0.01 bis 0.1)
- Der Markierungsradius sollte groß genug sein, um in der Zeichnung sichtbar zu sein, aber klein genug, um Details nicht zu verdecken
- Ausgabedateien werden nicht überschrieben, da jede Datei einen eindeutigen Zeitstempel erhält
## Fehlerbehebung
##### "Datei nicht gefunden"
Überprüfen Sie den Pfad zur DXF-Datei oder legen Sie Dateien im `input/`-Verzeichnis ab.
##### "Keine Schnittpunkte gefunden"
- Prüfen Sie, ob die in `config.cfg` angegebenen Layer in der DXF-Datei existieren
- Erhöhen Sie den TOLERANCE-Wert in `config.cfg`, falls Linien nicht exakt verbunden sind
##### Python-Fehler
Stellen Sie sicher, dass alle erforderlichen Python-Bibliotheken installiert sind.
##### Drag & Drop funktioniert nicht
Stellen Sie sicher, dass Sie die Datei auf `verbindungszaehler.bat` (nicht auf `setenv.bat`) ziehen.
## Autor
Simon Hensch
+143
View File
@@ -0,0 +1,143 @@
# VZAEHLER — Verbindungszähler für BricsCAD
Automatische Erkennung und Klassifikation von Linienschnittpunkten auf definierten Layern.
---
## Voraussetzungen
- BricsCAD mit LISP-Unterstützung
- Zeichnung mit Linien (`LINE`) auf den zu prüfenden Layern
- Skriptdatei: `verbindungszaehler.lsp`
> **Wichtig:** Es werden ausschließlich Verbindungspunkte erkannt, die auf der selben Z-Koordinate liegen.
---
## Installation
Skript laden:
```lisp
(load "R:/pfad/zur/verbindungszaehler.lsp")
```
Oder über die AutoCAD/BricsCAD Befehlszeile:
```
APPLOAD → Datei auswählen → Laden
```
---
## Verwendung
Befehl in der Befehlszeile eingeben:
```
VZAEHLER
```
### Eingabeaufforderungen
| Eingabe | Beschreibung | Default |
|---|---|---|
| Layer | Kommagetrennte Liste der zu prüfenden Layer | `D-1, D-5` |
| Toleranz | Maximaler Abstand in Zeichnungseinheiten für Toleranzverbindungen | `0.50` |
Bei einfachem `Return` wird jeweils der Defaultwert verwendet.
**Beispiel:**
```
===== VERBINDUNGSZAEHLER =====
Layer (kommagetrennt) [D-1, D-5]: D-1, D-3
Toleranz [0.50]:
Layer : D-1 D-3
Toleranz : 0.50
------------------------------
Linien gefunden: 42
```
---
## Verbindungstypen
Das Skript unterscheidet drei Typen:
| Typ | Beschreibung | Erkennungslogik | Layer | Farbe |
|---|---|---|---|---|
| **Kreuzung** | Zwei Linien kreuzen sich, Schnittpunkt liegt im Inneren beider Linien | Nur echter geometrischer Schnitt, toleranzunabhängig | `D-KREUZUNG` | Rot (1) |
| **T-Verbindung** | Ein Endpunkt liegt auf dem Inneren der anderen Linie | Toleranzbasiert | `D-T_VERBINDUNG` | Grün (3) |
| **Eckverbindung** | Zwei Endpunkte berühren sich | Toleranzbasiert | `D-ECKVERBINDUNG` | Gelb (5) |
> **Wichtig:** Kreuzungen werden ausschließlich über echten geometrischen Schnitt erkannt — niemals über Toleranz. T-Verbindungen und Eckverbindungen werden niemals als Kreuzung klassifiziert, auch wenn sich die verlängerten Linien schneiden würden.
---
## Ergebnis in der Zeichnung
An jedem erkannten Verbindungspunkt wird ein Kreis (Radius 100 Einheiten) auf dem jeweiligen Ergebnislayer gezeichnet. Die Layer werden automatisch angelegt falls sie noch nicht existieren.
---
## Ausgabedatei
Nach der Auswertung wird automatisch eine Textdatei im Verzeichnis der Zeichnung erstellt:
```
<Zeichnungsname>_<YYYYMMDD-HHMMSS>_vzaehler.txt
```
**Beispiel:** `meinplan_20260507-143211_vzaehler.txt`
### Inhalt der Ausgabedatei
```
================================================
VERBINDUNGSZAEHLER - ERGEBNIS
================================================
Datum/Zeit : 07.05.2026 14:32:11
Zeichnung : R:\projekte\meinplan.dwg
Layer : D-1, D-5
------------------------------------------------
VERBINDUNGSTYPEN
------------------------------------------------
Kreuzungen : 3
T-Verbindungen : 8
Eckverbindungen : 12
------------------------------------------------
SUMMEN
------------------------------------------------
Kreuzungen : 3
Kontaktpunkte (T + Eck) : 20
davon T-Verbindungen : 8
davon Eckverbindungen : 12
GESAMT : 23
================================================
```
---
## Toleranz — Hinweise
Die Toleranz wirkt **ausschließlich** auf T-Verbindungen und Eckverbindungen:
- Zu **klein**: Echte Verbindungen werden nicht erkannt (z.B. bei minimal versetzten Endpunkten durch Zeichenungenauigkeit)
- Zu **groß**: Linien die sich nicht berühren werden fälschlich als verbunden gezählt
- Empfehlung: Toleranz an die Zeichnungsgenauigkeit anpassen, typisch `0.1` bis `1.0` Zeichnungseinheiten (mm bei metrischer Konfiguration)
---
## Bekannte Einschränkungen
- Es werden nur Objekte vom Typ `LINE` ausgewertet — keine Polylinien, Bögen oder Splines
- Die Auswertung erfolgt in 2D (XY-Ebene), Z-Koordinaten werden ignoriert
- Bei sehr großen Zeichnungen (1000+ Linien) kann die Laufzeit spürbar steigen, da alle Linienpaare gegeneinander geprüft werden (O(n²))
+587
View File
@@ -0,0 +1,587 @@
(vl-load-com)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SAFE UTIL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun safe-num (x)
(if (numberp x) x 0.0)
)
(defun safe-vec (v)
(cond
((and (listp v) (>= (length v) 2))
(list (safe-num (car v)) (safe-num (cadr v))))
((listp v)
'(0.0 0.0))
(T '(0.0 0.0))
)
)
(defun clean-point (p)
(if (and p (listp p))
(list
(safe-num (car p))
(safe-num (cadr p))
)
'(0.0 0.0)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; LAYER MANAGEMENT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun ensure-layer (name color / doc layers layerObj)
(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
(setq layers (vla-get-Layers doc))
(if (not (tblsearch "LAYER" name))
(setq layerObj (vla-add layers name))
(setq layerObj (vla-item layers name))
)
(vla-put-Color layerObj color)
layerObj
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GEOMETRY CORE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun point-distance (a b)
(sqrt
(+ (expt (- (car a) (car b)) 2)
(expt (- (cadr a) (cadr b)) 2)))
)
(defun vec-sub (a b)
(setq a (safe-vec a))
(setq b (safe-vec b))
(list (- (car a) (car b))
(- (cadr a) (cadr b)))
)
(defun point-distance-segment (p a b / ap ab denom t-val proj)
(setq p (safe-vec p))
(setq a (safe-vec a))
(setq b (safe-vec b))
(setq ap (vec-sub p a))
(setq ab (vec-sub b a))
;; GUARD: ab muss eine Liste mit 2 Zahlen sein
(if (not (and (listp ab)
(= (length ab) 2)
(numberp (car ab))
(numberp (cadr ab))))
(point-distance p a) ;; Fallback
(progn
(setq denom (+ (* (car ab) (car ab))
(* (cadr ab) (cadr ab))))
(if (<= denom 1e-12)
(point-distance p a)
(progn
(setq t-val (/ (+ (* (car ap) (car ab))
(* (cadr ap) (cadr ab)))
denom))
(setq t-val (safe-num t-val))
(if (< t-val 0.0) (setq t-val 0.0))
(if (> t-val 1.0) (setq t-val 1.0))
(setq proj (list (+ (car a) (* t-val (car ab)))
(+ (cadr a) (* t-val (cadr ab)))))
(point-distance p proj)
)
)
)
)
)
;; Liegt ein Punkt strikt zwischen den Endpunkten einer Linie?
;; (nicht am Endpunkt, mit kleiner Toleranz für numerischen Drift)
(defun point-on-segment-interior (pt a b tol / t-val ab ap denom)
(setq ab (vec-sub b a))
(setq ap (vec-sub pt a))
(setq denom (+ (* (car ab) (car ab)) (* (cadr ab) (cadr ab))))
(if (<= denom 1e-12)
nil
(progn
(setq t-val (/ (+ (* (car ap) (car ab)) (* (cadr ap) (cadr ab))) denom))
;; "innen" = klar weg von beiden Endpunkten
(and (> t-val (/ tol (sqrt denom)))
(< t-val (- 1.0 (/ tol (sqrt denom)))))
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Endpunkt-zu-Endpunkt Prüfung (Stoß-Erkennung)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun endpoints-touch-raw (l1 l2 tol / p1 p2 p3 p4)
;; Rohpunkte direkt aus der Linienliste (clean-point bereits angewendet)
(setq p1 (clean-point (car l1)))
(setq p2 (clean-point (cadr l1)))
(setq p3 (clean-point (car l2)))
(setq p4 (clean-point (cadr l2)))
(cond
((< (point-distance p1 p3) tol) p1)
((< (point-distance p1 p4) tol) p1)
((< (point-distance p2 p3) tol) p2)
((< (point-distance p2 p4) tol) p2)
(T nil)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; INTERSECTION CORE (SAFE + TOLERANT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun intersect-lines (l1 l2 / o1 o2 result arr)
(setq o1 (vlax-ename->vla-object (caddr l1)))
(setq o2 (vlax-ename->vla-object (caddr l2)))
(setq result
(vl-catch-all-apply
'vla-IntersectWith
(list o1 o2 0)
)
)
(if (vl-catch-all-error-p result)
nil
(progn
(setq result
(vl-catch-all-apply 'vlax-variant-value (list result))
)
(if (vl-catch-all-error-p result)
(setq result (vla-IntersectWith o1 o2 0))
)
(setq arr
(vl-catch-all-apply 'vlax-safearray->list (list result))
)
(if (vl-catch-all-error-p arr)
nil
(if (>= (length arr) 3)
(list (nth 0 arr) (nth 1 arr) 0.0)
)
)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PIPELINE INTERSECTION (MAIN BRAIN)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; normalize-point ersatzlos streichen
(defun find-intersection (l1 l2 tol / p1 p2 p3 p4 ip touch-pt)
(if (not (and (listp l1) (listp (car l1))
(listp l2) (listp (car l2))))
nil
(progn
(setq p1 (clean-point (car l1)))
(setq p2 (clean-point (cadr l1)))
(setq p3 (clean-point (car l2)))
(setq p4 (clean-point (cadr l2)))
;; Schritt 1: Endpunkt-Stoß
(setq touch-pt (endpoints-touch-raw l1 l2 tol))
(if touch-pt
(cons touch-pt (classify-intersection touch-pt l1 l2 tol))
;; Schritt 2: Echter Schnitt
(progn
(setq ip (intersect-lines l1 l2))
(if ip
(progn
;; Sicherheitsnetz: liegt SP nahe einem Endpunkt?
(if (or (< (point-distance ip p1) tol)
(< (point-distance ip p2) tol)
(< (point-distance ip p3) tol)
(< (point-distance ip p4) tol))
(cons ip (classify-intersection ip l1 l2 tol))
(if (and (point-on-segment-interior ip p1 p2 tol)
(point-on-segment-interior ip p3 p4 tol))
(cons ip "Kreuzung")
(cons ip (classify-intersection ip l1 l2 tol))
)
)
)
;; Schritt 3: Toleranz-Fallback
(cond
((< (point-distance-segment p1 p3 p4) tol)
(cons p1 (classify-intersection p1 l1 l2 tol)))
((< (point-distance-segment p2 p3 p4) tol)
(cons p2 (classify-intersection p2 l1 l2 tol)))
((< (point-distance-segment p3 p1 p2) tol)
(cons p3 (classify-intersection p3 l1 l2 tol)))
((< (point-distance-segment p4 p1 p2) tol)
(cons p4 (classify-intersection p4 l1 l2 tol)))
(T nil)
)
)
)
)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; CLASSIFICATION
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun is-endpoint (pt line tol)
(or
(< (point-distance pt (car line)) tol)
(< (point-distance pt (cadr line)) tol)
)
)
(defun classify-intersection (pt l1 l2 tol / e1 e2)
(setq e1 (is-endpoint pt l1 tol))
(setq e2 (is-endpoint pt l2 tol))
(cond
((and e1 e2) "Eckverbindung")
((or e1 e2) "T-Verbindung")
(T "Kreuzung")
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; DEDUP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun point-exists (pt list tol)
(vl-some
'(lambda (p)
(< (point-distance pt p) tol)
)
list
)
)
(defun count-by-type (lst typ)
(length
(vl-remove-if-not
'(lambda (p) (= (caddr p) typ))
lst
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; DRAW
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun create-circle (pt radius layer)
(entmakex
(list
'(0 . "CIRCLE")
(cons 8 layer)
(cons 10 pt)
(cons 40 radius)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; INPUT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun get-lines-by-layer (layers / ss i ent obj lines)
(setq lines '())
(foreach lay layers
(setq ss
(ssget "_X"
(list '(0 . "LINE") (cons 8 lay))
)
)
(if ss
(progn
(setq i 0)
(repeat (sslength ss)
(setq ent (ssname ss i))
(setq obj (vlax-ename->vla-object ent))
(setq lines
(cons
(list
(clean-point (vlax-get obj 'StartPoint))
(clean-point (vlax-get obj 'EndPoint))
ent
)
lines
)
)
(setq i (1+ i))
)
)
)
)
lines
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; TEXTDATEI-EXPORT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun write-report (all-pts filepath layers / f n-kr n-tv n-ek n-kontakt n-gesamt)
(setq n-kr (count-by-type all-pts "Kreuzung"))
(setq n-tv (count-by-type all-pts "T-Verbindung"))
(setq n-ek (count-by-type all-pts "Eckverbindung"))
(setq n-kontakt (+ n-tv n-ek))
(setq n-gesamt (length all-pts))
(setq f (open filepath "w"))
(if (not f)
(prompt (strcat "\nFehler: Datei konnte nicht erstellt werden: " filepath))
(progn
(write-line "================================================" f)
(write-line " VERBINDUNGSZAEHLER - ERGEBNIS" f)
(write-line "================================================" f)
(write-line "" f)
(write-line (strcat " Datum/Zeit : " (menucmd "M=$(edtime,$(getvar,DATE),DD.MM.YYYY HH:MM:SS)")) f)
(write-line (strcat " Zeichnung : " (vla-get-FullName (vla-get-ActiveDocument (vlax-get-acad-object)))) f)
;; Layer-Zeile im Report dynamisch:
(write-line
(strcat " Layer : "
(apply 'strcat
(cons (car layers)
(mapcar '(lambda (l) (strcat ", " l)) (cdr layers))
)
)
)
f
)
(write-line "" f)
(write-line "------------------------------------------------" f)
(write-line " VERBINDUNGSTYPEN" f)
(write-line "------------------------------------------------" f)
(write-line "" f)
(write-line (strcat " Kreuzungen : " (itoa n-kr)) f)
(write-line (strcat " T-Verbindungen : " (itoa n-tv)) f)
(write-line (strcat " Eckverbindungen : " (itoa n-ek)) f)
(write-line "" f)
(write-line "------------------------------------------------" f)
(write-line " SUMMEN" f)
(write-line "------------------------------------------------" f)
(write-line "" f)
(write-line (strcat " Kreuzungen : " (itoa n-kr)) f)
(write-line (strcat " Kontaktpunkte (T + Eck) : " (itoa n-kontakt)) f)
(write-line (strcat " davon T-Verbindungen : " (itoa n-tv)) f)
(write-line (strcat " davon Eckverbindungen : " (itoa n-ek)) f)
(write-line "" f)
(write-line (strcat " GESAMT : " (itoa n-gesamt)) f)
(write-line "" f)
(write-line "================================================" f)
(close f)
(prompt (strcat "\nBericht gespeichert: " filepath))
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; INPUT MIT DEFAULTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun prompt-layers (default-layers / input parts result)
;; default-layers ist eine Liste z.B. '("D-1" "D-5")
(setq input
(getstring
(strcat "\nLayer (kommagetrennt) ["
(apply 'strcat
(cons (car default-layers)
(mapcar '(lambda (l) (strcat ", " l)) (cdr default-layers))
)
)
"]: ")
)
)
(if (= input "")
default-layers
;; Eingabe splitten an Komma, Whitespace trimmen
(progn
;; einfaches Splitten: Zeichen für Zeichen
(setq parts (split-string-by input ","))
(foreach p parts
(setq p (string-trim p))
(if (/= p "")
(setq result (cons p result))
)
)
(reverse result)
)
)
)
(defun prompt-tolerance (default-tol / input val)
(setq input
(getstring
(strcat "\nToleranz [" (rtos default-tol 2 2) "]: ")
)
)
(if (= input "")
default-tol
(progn
(setq val (atof input))
(if (> val 0.0)
val
(progn
(prompt (strcat "\nUngueltige Toleranz, verwende Default: " (rtos default-tol 2 2)))
default-tol
)
)
)
)
)
;; Hilfsfunktion: String an Trennzeichen splitten
(defun split-string-by (str sep / result current i ch)
(setq result '())
(setq current "")
(setq i 0)
(while (< i (strlen str))
(setq ch (substr str (1+ i) 1))
(if (= ch sep)
(progn
(setq result (cons current result))
(setq current "")
)
(setq current (strcat current ch))
)
(setq i (1+ i))
)
;; letztes Segment
(setq result (cons current result))
(reverse result)
)
;; Hilfsfunktion: führende/nachfolgende Leerzeichen entfernen
(defun string-trim (str / i j)
(setq i 1)
(setq j (strlen str))
(while (and (<= i j) (= (substr str i 1) " "))
(setq i (1+ i))
)
(while (and (>= j i) (= (substr str j 1) " "))
(setq j (1- j))
)
(if (> j (1- i))
(substr str i (- (1+ j) i))
""
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MAIN COMMAND
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:VZAEHLER (/ layers tol radius lines i j l1 l2 pt typ all-pts result report-path)
;; ── Defaults ────────────────────────────────────────────
(setq default-layers '("D-1" "D-5"))
(setq default-tol 0.5)
;; ── Benutzereingabe ──────────────────────────────────────
(prompt "\n===== VERBINDUNGSZAEHLER =====")
(setq layers (prompt-layers default-layers))
(setq tol (prompt-tolerance default-tol))
(setq radius 100)
(prompt (strcat "\nLayer : "))
(foreach l layers (prompt (strcat l " ")))
(prompt (strcat "\nToleranz : " (rtos tol 2 2)))
(prompt "\n------------------------------")
;; ── Logik ────────────────────────────────────
(setq all-pts '())
(setq lines (get-lines-by-layer layers))
(ensure-layer "D-KREUZUNG" 1)
(ensure-layer "D-T_VERBINDUNG" 3)
(ensure-layer "D-ECKVERBINDUNG" 5)
(prompt (strcat "\nLinien gefunden: " (itoa (length lines))))
(setq i 0)
(while (< i (length lines))
(setq j (+ i 1))
(while (< j (length lines))
(setq l1 (nth i lines))
(setq l2 (nth j lines))
(setq result (find-intersection l1 l2 tol))
(if result
(progn
(setq pt (car result)) ;; Punkt
(setq typ (cdr result)) ;; Typ — direkt aus find-intersection
(if (not (point-exists pt all-pts tol))
(progn
(setq all-pts (cons (list (car pt) (cadr pt) typ) all-pts))
(cond
((= typ "Kreuzung") (create-circle pt radius "D-KREUZUNG"))
((= typ "T-Verbindung") (create-circle pt radius "D-T_VERBINDUNG"))
((= typ "Eckverbindung") (create-circle pt radius "D-ECKVERBINDUNG"))
)
)
)
)
)
(setq j (1+ j))
)
(setq i (1+ i))
)
(prompt "\n\n===== ERGEBNIS =====")
(prompt (strcat "\nKreuzungen: " (itoa (count-by-type all-pts "Kreuzung"))))
(prompt (strcat "\nT-Verbindungen: " (itoa (count-by-type all-pts "T-Verbindung"))))
(prompt (strcat "\nEckverbindungen: " (itoa (count-by-type all-pts "Eckverbindung"))))
(prompt (strcat "\nGESAMT: " (itoa (length all-pts))))
;; ── Report schreiben ──────────────────────────────────────
(setq dwg-name
(vla-get-Name (vla-get-ActiveDocument (vlax-get-acad-object)))
)
;; ".dwg" abschneiden falls vorhanden
(if (wcmatch dwg-name "*.dwg")
(setq dwg-name (substr dwg-name 1 (- (strlen dwg-name) 4)))
)
(setq timestamp
(menucmd "M=$(edtime,$(getvar,DATE),YYYYMMDD-HHMMSS)")
)
(setq report-path
(strcat
(vla-get-Path (vla-get-ActiveDocument (vlax-get-acad-object)))
"\\"
dwg-name
"_"
timestamp
"_vzaehler.txt"
)
)
(write-report all-pts report-path layers)
(princ)
)
+145
View File
@@ -0,0 +1,145 @@
# DRT-Verbindungszähler - DXF-Analyse-Tool
Ein Python-basiertes Werkzeug zur automatischen Erkennung und Markierung von Schnittpunkten zwischen Linien in DXF-Dateien.
## Überblick
Dieses Projekt analysiert DXF-Dateien und identifiziert Verbindungs- bzw. Schnittpunkte zwischen Linien auf verschiedenen Layern. Die gefundenen Schnittpunkte werden mit Kreisen markiert und in einer separaten DXF-Datei sowie einem Textbericht ausgegeben.
## Projektstruktur
```text
verbindungszaehler/
├── verbindungszaehler.bat # Hauptskript zum Starten der Analyse
├── config/
│ └── config.cfg # Standardkonfiguration
├── scripts/
│ └── setenv.bat # Umgebungsvariablen und Verzeichnisstruktur
├── src/
│ └── lib/
│ ├── analyze.py # Python-Analyseskript
│ └── dxf_analyzer.py # Kernlogik
├── input/ # Eingabeverzeichnis für DXF-Dateien
└── output/ # Ausgabeverzeichnis für Ergebnisse
```
## Voraussetzungen
- Windows-Betriebssystem
- Python 3.x installiert und im PATH verfügbar
- Python-Bibliothek für DXF-Verarbeitung `ezdxf`
- Modul `dxf_analyzer.py` mit der Klasse `IntersectionAnalyzer`
## Installation
1. Projekt in ein beliebiges Verzeichnis entpacken
2. Sicherstellen, dass Python installiert ist
3. Benötigte Python-Pakete installieren (z.B. `pip install ezdxf`)
4. DXF-Dateien im `input/`-Verzeichnis ablegen
## Verwendung
### Methode 1: Alle Dateien im Input-Verzeichnis analysieren
Doppelklick auf `verbindungszaehler.bat` oder per Kommandozeile:
```batch
verbindungszaehler.bat
```
Alle DXF-Dateien im `input/`-Verzeichnis werden automatisch mit den Einstellungen aus `config.cfg` analysiert.
### Methode 2: Einzelne Datei per Drag & Drop
Ziehen Sie eine DXF-Datei direkt auf die `verbindungszaehler.bat` und lassen Sie sie los. Die Datei wird sofort mit den Einstellungen aus `config/config.cfg` analysiert.
### Methode 3: Einzelne Datei per Kommandozeile
```batch
verbindungszaehler.bat "C:\Pfad\zur\datei.dxf"
```
## Konfiguration
### config.cfg
Die Datei `config.example.cfg` enthält alle Einstellungen für die Analyse. Für individuelle Parameter muss eine Kopie von `config.example.cfg` erstellt und in `config.cfg` umbenannt werden. Diese dient nun als Konfigurationsdatei des Projekts.
Passen Sie diese Werte in `config.cfg` nach Bedarf an:
```cfg
LAYERS=D-1,D-5
TOLERANCE=0.06
MARK_RADIUS=150
```
**Parameter-Erklärung:**
- **LAYERS**: Kommagetrennte Liste der zu analysierenden Layer (z.B. "D-1,D-5,D-3")
- **TOLERANCE**: Maximaler Abstand in DXF-Einheiten, bei dem zwei Punkte als identisch gelten (für ungenaue Zeichnungen)
- **MARK_RADIUS**: Radius der Kreise in DXF-Einheiten, die Schnittpunkte markieren
**Hinweis:** Nach Änderungen in `config.cfg` werden die neuen Werte bei der nächsten Ausführung automatisch verwendet.
## Ausgabe
Das Tool erzeugt für jede analysierte DXF-Datei zwei Dateien im `output/`-Verzeichnis:
1. **[Dateiname]_markiert_[Datum]_[Zeit].dxf**
DXF-Datei mit eingezeichneten Kreisen an allen gefundenen Schnittpunkten
2. **[Dateiname]_analyse_[Datum]_[Zeit].txt**
Textbericht mit Details zu den gefundenen Verbindungen (Koordinaten, Anzahl, etc.)
**Beispiel:**
```text
zeichnung_markiert_20241202_14-30-25.dxf
zeichnung_analyse_20241202_14-30-25.txt
```
## Funktionsweise
1. **setenv.bat** richtet die Verzeichnisstruktur ein und lädt die Konfigurationswerte aus `config.cfg` im `config/`-Ordner
2. **verbindungszaehler.bat** verarbeitet die angegebene Datei (oder alle Dateien im Input-Ordner) und ruft das Python-Skript auf
3. **analyze.py** lädt die DXF-Datei und übergibt sie zusammen mit den Konfigurationsparametern an den `IntersectionAnalyzer`
4. Der Analyzer findet Schnittpunkte zwischen Linien auf den angegebenen Layern innerhalb der definierten Toleranz
5. Gefundene Schnittpunkte werden mit Kreisen (Radius aus `MARK_RADIUS`) markiert
6. Ergebnisse werden als neue DXF-Datei und Textbericht gespeichert
## Workflow-Beispiel
1. DXF-Dateien in den `input/`-Ordner kopieren
2. `config.cfg` im `config/`-Ordner öffnen und gewünschte Layer-Namen, Toleranz und Markierungsradius eintragen
3. `verbindungszaehler.bat` per Doppelklick starten **oder** eine einzelne DXF-Datei auf die Batch-Datei ziehen
4. Ergebnisse im `output/`-Ordner überprüfen: **Bevor die Anzahl der Verbindungen weiter verwendet wird, sind die markierten Punkte im Ausgabelayout zwingend auf Fehler zu überprüfen!**
## Hinweise
- Stellen Sie sicher, dass die Layer-Namen in `config.cfg` exakt mit denen in der DXF-Datei übereinstimmen (Groß-/Kleinschreibung beachten)
- Bei sehr großen Dateien kann die Analyse einige Zeit in Anspruch nehmen
- Die Toleranz sollte an die Genauigkeit Ihrer Zeichnungen angepasst werden (typische Werte: 0.01 bis 0.1)
- Der Markierungsradius sollte groß genug sein, um in der Zeichnung sichtbar zu sein, aber klein genug, um Details nicht zu verdecken
- Ausgabedateien werden nicht überschrieben, da jede Datei einen eindeutigen Zeitstempel erhält
## Fehlerbehebung
##### "Datei nicht gefunden"
Überprüfen Sie den Pfad zur DXF-Datei oder legen Sie Dateien im `input/`-Verzeichnis ab.
##### "Keine Schnittpunkte gefunden"
- Prüfen Sie, ob die in `config.cfg` angegebenen Layer in der DXF-Datei existieren
- Erhöhen Sie den TOLERANCE-Wert in `config.cfg`, falls Linien nicht exakt verbunden sind
##### Python-Fehler
Stellen Sie sicher, dass alle erforderlichen Python-Bibliotheken installiert sind.
##### Drag & Drop funktioniert nicht
Stellen Sie sicher, dass Sie die Datei auf `verbindungszaehler.bat` (nicht auf `setenv.bat`) ziehen.
## Autor
Simon Hensch
+8
View File
@@ -0,0 +1,8 @@
# Alle Linien, die auf den angegebenen Layern liegen, werden in der Berechnung berücksichtigt
LAYERS=D-1,D-5
# Toleranz der Schnittpunkte insbesondere bei T-Verbindungen in Millimetern. Beim Überschreiten der Toleranz wird die Verbindung nicht gezählt.
TOLERANCE=15
# Alle erkannten Verbindungen werden mit einem Kreis des Radius in Millimetern markiert.
MARK_RADIUS=150
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,241 @@
============================================================
DXF SCHNITTPUNKT-ANALYSE ERGEBNIS - 16.04.2026 09:25:49
============================================================
Eingabedatei: C:\Users\s.hensch\Git\drt-verbindungszaehler\input\500658_10_1_ohne_statLager_Verbindungselemente_20260416_SH.dxf
Analysierte Layer: D-1, D-5
Anzahl analysierter Linien: 164
------------------------------------------------------------
SCHNITTPUNKT-STATISTIK
------------------------------------------------------------
Kreuzung : 6 ( 2.9%)
T-Verbindung : 201 ( 95.7%)
Eckverbindung : 3 ( 1.4%)
GESAMT : 210
------------------------------------------------------------
DETAILS DER SCHNITTPUNKTE
------------------------------------------------------------
Kreuzung (6 Stück):
----------------------------------------
1. X= 79401.213, Y= 397.810
2. X= 83401.213, Y= 397.810
3. X= 87401.213, Y= 397.810
4. X= 91401.213, Y= 397.810
5. X= 73501.687, Y= 10597.810
6. X=134124.793, Y= 10391.879
T-Verbindung (201 Stück):
----------------------------------------
1. X=138308.726, Y= 63200.924
2. X=138308.726, Y= 52442.951
3. X=138308.726, Y= 54442.951
4. X=138308.726, Y= 56442.951
5. X=138308.726, Y= 58442.951
6. X=138308.726, Y= 60442.951
7. X=138308.726, Y= 62086.693
8. X=128510.648, Y= 63200.924
9. X=128510.648, Y= 52441.370
10. X=128510.648, Y= 54441.370
11. X=128510.648, Y= 56441.370
12. X=128510.648, Y= 58441.370
13. X=128510.648, Y= 60441.370
14. X=128510.648, Y= 61565.879
15. X=128510.648, Y= 61160.000
16. X=139558.726, Y= 63200.924
17. X=130960.648, Y= 63200.924
18. X=133410.648, Y= 63200.924
19. X=135860.648, Y= 63200.924
20. X=126279.842, Y= 52441.370
21. X=126279.842, Y= 54441.370
22. X=126279.842, Y= 56441.370
23. X=126279.842, Y= 58441.370
24. X=126279.842, Y= 60441.370
25. X=126279.842, Y= 61565.879
26. X=126279.842, Y= 51780.000
27. X=126279.842, Y= 53878.216
28. X=139558.726, Y= 52442.951
29. X=139558.726, Y= 54442.951
30. X=139558.726, Y= 56442.951
31. X=139558.726, Y= 58442.951
32. X=139558.726, Y= 60442.951
33. X=139558.726, Y= 62086.693
34. X= 77401.213, Y= 397.810
35. X= 81401.213, Y= 397.810
36. X= 85401.213, Y= 397.810
37. X= 89401.213, Y= 397.810
38. X= 93401.213, Y= 397.810
39. X= 95088.723, Y= 397.810
40. X= 77401.153, Y= 1547.810
41. X= 79401.153, Y= 1547.810
42. X= 81401.153, Y= 1547.810
43. X= 83401.153, Y= 1547.810
44. X= 85401.153, Y= 1547.810
45. X= 87401.153, Y= 1547.810
46. X= 89401.153, Y= 1547.810
47. X= 91401.153, Y= 1547.810
48. X= 93401.153, Y= 1547.810
49. X= 95088.663, Y= 1547.810
50. X= 95180.000, Y= 5747.810
51. X= 95977.004, Y= 5747.810
52. X= 97051.644, Y= 8147.810
53. X= 95180.000, Y= 8147.810
54. X= 95977.004, Y= 8147.810
55. X= 75394.609, Y= 10597.810
56. X= 77400.687, Y= 10597.810
57. X= 79400.687, Y= 10597.810
58. X= 81400.687, Y= 10597.810
59. X= 83400.687, Y= 10597.810
60. X= 85400.687, Y= 10597.810
61. X= 87400.687, Y= 10597.810
62. X= 89400.687, Y= 10597.810
63. X= 91400.687, Y= 10597.810
64. X= 93400.687, Y= 10597.810
65. X= 73501.687, Y= 11896.713
66. X= 75394.609, Y= 11896.810
67. X= 77400.620, Y= 11896.914
68. X= 79400.620, Y= 11897.017
69. X= 81400.620, Y= 11897.120
70. X= 83400.620, Y= 11897.223
71. X= 85400.620, Y= 11897.326
72. X= 87400.620, Y= 11897.429
73. X= 89400.620, Y= 11897.532
74. X= 91400.620, Y= 11897.635
75. X= 93400.620, Y= 11897.738
76. X=130051.644, Y= 8191.879
77. X=130051.644, Y= 6943.978
78. X=132251.644, Y= 8191.879
79. X=132251.644, Y= 6943.978
80. X=125651.644, Y= 7421.473
81. X=127851.644, Y= 7421.473
82. X=133383.730, Y= 8191.879
83. X=133383.730, Y= 6943.978
84. X=147324.793, Y= 11803.549
85. X=147324.793, Y= 10926.143
86. X=151424.793, Y= 11803.549
87. X=151424.793, Y= 10926.143
88. X=155924.793, Y= 11803.549
89. X=155924.793, Y= 10926.143
90. X=149424.793, Y= 11803.549
91. X=153724.793, Y= 11803.549
92. X=160424.793, Y= 11803.549
93. X=164924.793, Y= 11803.549
94. X=169424.793, Y= 11803.549
95. X=173924.793, Y= 11803.549
96. X=178424.793, Y= 11803.549
97. X=158124.793, Y= 11803.549
98. X=162624.793, Y= 11803.549
99. X=167124.793, Y= 11803.549
100. X=171624.793, Y= 11803.549
101. X=176124.793, Y= 11803.549
102. X=149424.793, Y= 10926.143
103. X=153724.793, Y= 10926.143
104. X=160424.793, Y= 10926.143
105. X=164924.793, Y= 10926.143
106. X=169424.793, Y= 10926.143
107. X=173924.793, Y= 10926.143
108. X=178424.793, Y= 10926.143
109. X=158124.793, Y= 10926.143
110. X=162624.793, Y= 10926.143
111. X=167124.793, Y= 10926.143
112. X=171624.793, Y= 10926.143
113. X=176124.793, Y= 10926.143
114. X=156485.708, Y= 13474.648
115. X=158485.708, Y= 13474.648
116. X=160485.708, Y= 13474.648
117. X=162485.708, Y= 13474.648
118. X=164485.708, Y= 13474.648
119. X=166485.708, Y= 13474.648
120. X=168485.708, Y= 13474.648
121. X=170485.708, Y= 13474.648
122. X=172485.708, Y= 13474.648
123. X=174485.708, Y= 13474.648
124. X=176485.708, Y= 13474.648
125. X=178005.866, Y= 13474.648
126. X=156485.708, Y= 12404.648
127. X=158485.708, Y= 12404.648
128. X=160485.708, Y= 12404.648
129. X=162485.708, Y= 12404.648
130. X=164485.708, Y= 12404.648
131. X=166485.708, Y= 12404.648
132. X=168485.708, Y= 12404.648
133. X=170485.708, Y= 12404.648
134. X=172485.708, Y= 12404.648
135. X=174485.708, Y= 12404.648
136. X=176485.708, Y= 12404.648
137. X=178005.866, Y= 12404.648
138. X=130960.648, Y= 61160.000
139. X=120387.520, Y= 51780.000
140. X=121006.726, Y= 51780.000
141. X=123465.272, Y= 51780.000
142. X=125006.726, Y= 51780.000
143. X=120387.520, Y= 53878.216
144. X=121006.726, Y= 53878.216
145. X=123465.272, Y= 53878.216
146. X=125006.726, Y= 53878.216
147. X=120387.520, Y= 52829.108
148. X=121006.726, Y= 52829.108
149. X=144732.392, Y= 53286.846
150. X=144732.392, Y= 55286.846
151. X=144732.392, Y= 57286.846
152. X=144732.392, Y= 59286.846
153. X=144732.392, Y= 60686.578
154. X=146632.860, Y= 53286.846
155. X=146632.860, Y= 55286.846
156. X=146632.860, Y= 57286.846
157. X=146632.860, Y= 59286.846
158. X=146632.860, Y= 60686.578
159. X=145682.626, Y= 53286.846
160. X=145682.626, Y= 52819.128
161. X= 76800.000, Y= 65085.000
162. X= 78800.000, Y= 65085.000
163. X= 80800.000, Y= 65085.000
164. X= 82800.000, Y= 65085.000
165. X= 84800.000, Y= 65085.000
166. X= 72300.000, Y= 65085.000
167. X= 74800.000, Y= 65085.000
168. X= 73361.274, Y= 65085.000
169. X= 76800.000, Y= 64015.000
170. X= 78800.000, Y= 64015.000
171. X= 80800.000, Y= 64015.000
172. X= 82800.000, Y= 64015.000
173. X= 84800.000, Y= 64015.000
174. X= 72300.000, Y= 64015.000
175. X= 74800.000, Y= 64015.000
176. X= 73361.274, Y= 64015.000
177. X= 85849.346, Y= 64015.000
178. X=125651.644, Y= 1588.300
179. X=125651.644, Y= 3588.300
180. X=125651.644, Y= 5588.300
181. X=125651.644, Y= 630.889
182. X=127851.644, Y= 1588.300
183. X=127851.644, Y= 3588.300
184. X=127851.644, Y= 5588.300
185. X=127851.644, Y= 630.889
186. X= 95180.000, Y= 7190.000
187. X= 95977.004, Y= 7190.000
188. X=126280.000, Y= 1588.300
189. X=126280.000, Y= 630.889
190. X=147880.000, Y= 64274.648
191. X=149880.000, Y= 64274.648
192. X=151880.000, Y= 64274.648
193. X=153880.000, Y= 64274.648
194. X=155880.000, Y= 64274.648
195. X=147202.099, Y= 64274.648
196. X=147880.000, Y= 63204.648
197. X=149880.000, Y= 63204.648
198. X=151880.000, Y= 63204.648
199. X=153880.000, Y= 63204.648
200. X=155880.000, Y= 63204.648
201. X=147202.099, Y= 63204.648
Eckverbindung (3 Stück):
----------------------------------------
1. X=144732.392, Y= 52819.128
2. X=146632.860, Y= 52819.128
3. X= 85849.346, Y= 65085.000