Add Connections to SSG_LIB, reusing the TRO mechanisms
A connection is a CONNECTION_ARROW block sitting at the midpoint of an arrow
between two TRO markers. It stores the relationship as attributes rather than by
position:
TRO11 ----------> TRO14
UID 0062 UID 0065
Same architecture as the TRO feature, nothing new introduced:
Blockname CONNECTION_* -> c:CONNECTION_EDIT (Lisp/Connection_Edit.lsp)
-> dcl/connection_edit.dcl
The double-click and EATTEDIT hooks already route every INSERT through
SSG_BLOCKEDIT, so this is one more branch in that dispatcher - placed before the
TRO branch since both come from the same annotation run and the patterns must not
overlap. DCL path from DXFM_DCL, ssg-start/ssg-end, ssg-attrib-read and
ssg-attrib-set-on, all text via ssg-text/ssg-textf with 16 new keys in both
language files. Loading is lazy: not preloaded in the MNL, pulled by the menu
macros and the dispatcher with (ssg-ensure "Connection_Edit"), with a fallback to
native EATTEDIT if the module is missing.
CONNECTION_INSERT picks two TRO markers and draws the connection; the new
internal number comes from ssg-id-max/ssg-id-format, so it stays inside the
SSG_LIB number space. It refuses when the block definition is absent - the shape
comes from tro_annotate.py, this command does not invent one.
Menu: SSG_LIB > Connections with Verbindung einfuegen, Verbindung bearbeiten and
Bearbeiten (Auto), plus an entry in the POP501 edit context menu.
On the internal id: the markers keep their visible ID (TRO11) untouched - the
existing TRO_INSERT/tro-naechste-id read it and the request was explicit about
not changing it. The permanent unique number therefore lives in a separate
attribute UID, in the same four-digit space as ssg_id and the CSV TeileId.
Putting it into ID was tried and reverted: IDSCHECK treats ID as numeric and
would have overwritten TRO11 with a number while correcting duplicates.
Connections reference the UIDs, so the relationship survives a renamed or moved
marker.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
;; ============================================================
|
||||
;; CONNECTION_EDIT.LSP - Verbindungen zwischen TROs
|
||||
;;
|
||||
;; Eine Verbindung ist ein Block CONNECTION_ARROW in der Mitte eines Pfeils
|
||||
;; zwischen zwei TRO-Markern. Sie haelt die Beziehung ueber die *internen* IDs
|
||||
;; der beiden TROs fest, nicht ueber die Lage im Plan:
|
||||
;;
|
||||
;; TRO11 ----------> TRO14
|
||||
;; ID 0062 ID 0065
|
||||
;;
|
||||
;; Attribute des Verbindungsblocks:
|
||||
;; ID unsichtbar - eindeutige interne Nummer (ID-Raum von SSG_LIB)
|
||||
;; FROM_ID unsichtbar - interne ID der Quelle
|
||||
;; TO_ID unsichtbar - interne ID des Ziels
|
||||
;; FROM_TRO sichtbar - sprechender Name der Quelle
|
||||
;; TO_TRO sichtbar - sprechender Name des Ziels
|
||||
;; KIND unsichtbar - flow | colocated
|
||||
;;
|
||||
;; Warum interne IDs: der sprechende Name darf sich aendern (TRO_EDIT), die
|
||||
;; interne ID nicht. Ein DXF-Export kann die Beziehung damit eindeutig
|
||||
;; rekonstruieren, auch wenn Marker verschoben oder umbenannt wurden.
|
||||
;;
|
||||
;; Befehle:
|
||||
;; CONNECTION_INSERT - zwei TRO-Marker waehlen, Verbindung einzeichnen
|
||||
;; CONNECTION_EDIT - Quelle/Ziel einer bestehenden Verbindung aendern
|
||||
;;
|
||||
;; Aufruf:
|
||||
;; - Doppelklick auf die Verbindung -> ***DOUBLECLICK [INSERT] -> SSG_BLOCKEDIT
|
||||
;; - EATTEDIT -> c:EATTEDIT -> SSG_BLOCKEDIT
|
||||
;; - Menue SSG_LIB > Connections
|
||||
;; Der Dispatcher SSG_BLOCKEDIT leitet Blocknamen "CONNECTION_*" hierher.
|
||||
;;
|
||||
;; Setzt ssg_core.lsp (ssg-start/ssg-end, ssg-attrib-*), ssg_lang.lsp und
|
||||
;; ssg_id.lsp (ssg-id-max, ssg-id-format) voraus.
|
||||
;; ============================================================
|
||||
|
||||
(setq *connection-block* "CONNECTION_ARROW")
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; Attribut eines Blocks lesen ("" wenn nicht vorhanden)
|
||||
;; ------------------------------------------------------------
|
||||
(defun con-attrib (ent tag / wert)
|
||||
(setq wert (cdr (assoc tag (ssg-attrib-read ent))))
|
||||
(if wert wert "")
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; Einen TRO-Marker waehlen; liefert (ename interne-ID sprechender-Name)
|
||||
;; oder nil bei Abbruch bzw. falschem Block.
|
||||
;; ------------------------------------------------------------
|
||||
(defun con-pick-tro (prompt-key / sel ent bname)
|
||||
(setq sel (entsel (ssg-text prompt-key)))
|
||||
(if (null sel)
|
||||
nil
|
||||
(progn
|
||||
(setq ent (car sel)
|
||||
bname (cdr (assoc 2 (entget ent))))
|
||||
(if (not (wcmatch bname "TRO_*"))
|
||||
(progn (alert (ssg-textf "con-kein-tro" (list bname))) nil)
|
||||
(list ent (con-attrib ent "ID") (con-attrib ent "TRO_ID"))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; C:CONNECTION_INSERT - Verbindung zwischen zwei TRO-Markern einzeichnen
|
||||
;;
|
||||
;; Zeichnet Schaft und Spitze auf den Fluss-Layer und setzt den
|
||||
;; Verbindungsblock in die Mitte, ausgerichtet entlang des Pfeils.
|
||||
;; ------------------------------------------------------------
|
||||
(defun c:CONNECTION_INSERT ( / von nach p1 p2 dx dy laenge winkel mitte
|
||||
kopf ent-neu neue-id layer-name)
|
||||
(ssg-start "CONNECTION_INSERT" '(("OSMODE") ("ATTREQ") ("ATTDIA") ("CLAYER")))
|
||||
(setvar "OSMODE" 0)
|
||||
|
||||
(if (not (tblsearch "BLOCK" *connection-block*))
|
||||
(progn
|
||||
(alert (ssg-textf "con-block-fehlt" (list *connection-block*)))
|
||||
(ssg-end)
|
||||
(exit)
|
||||
)
|
||||
)
|
||||
|
||||
(setq von (con-pick-tro "con-quelle-waehlen"))
|
||||
(if (null von) (progn (ssg-end) (exit)))
|
||||
(setq nach (con-pick-tro "con-ziel-waehlen"))
|
||||
(if (null nach) (progn (ssg-end) (exit)))
|
||||
|
||||
(if (= (car von) (car nach))
|
||||
(progn (alert (ssg-text "con-gleicher-block")) (ssg-end) (exit))
|
||||
)
|
||||
|
||||
(setq p1 (cdr (assoc 10 (entget (car von))))
|
||||
p2 (cdr (assoc 10 (entget (car nach)))))
|
||||
(setq dx (- (car p2) (car p1))
|
||||
dy (- (cadr p2) (cadr p1))
|
||||
laenge (distance p1 p2))
|
||||
(if (<= laenge 1e-6)
|
||||
(progn (alert (ssg-text "con-gleicher-punkt")) (ssg-end) (exit))
|
||||
)
|
||||
(setq winkel (atan dy dx)
|
||||
mitte (list (/ (+ (car p1) (car p2)) 2.0)
|
||||
(/ (+ (cadr p1) (cadr p2)) 2.0)
|
||||
0.0))
|
||||
|
||||
;; Layer wie die uebrigen Verbindungen der Beschriftung
|
||||
(setq layer-name "TRO_FLOW")
|
||||
(ssg-make-layer layer-name "5" T)
|
||||
|
||||
;; Schaft
|
||||
(entmake (list (cons 0 "LWPOLYLINE")
|
||||
(cons 100 "AcDbEntity")
|
||||
(cons 8 layer-name)
|
||||
(cons 100 "AcDbPolyline")
|
||||
(cons 90 2)
|
||||
(cons 70 0)
|
||||
(cons 10 (list (car p1) (cadr p1)))
|
||||
(cons 10 (list (car p2) (cadr p2)))))
|
||||
|
||||
;; Verbindungsblock in die Mitte, entlang des Pfeils gedreht
|
||||
(setvar "ATTREQ" 0)
|
||||
(setvar "ATTDIA" 0)
|
||||
(command "_.-INSERT" *connection-block* mitte "" "" (angtos winkel 0 8))
|
||||
(setq ent-neu (entlast))
|
||||
|
||||
;; Eindeutige interne ID im ID-Raum von SSG_LIB
|
||||
(setq neue-id (ssg-id-format (1+ (ssg-id-max))))
|
||||
(ssg-attrib-set-on ent-neu
|
||||
(list (cons "ID" neue-id)
|
||||
(cons "FROM_ID" (cadr von))
|
||||
(cons "TO_ID" (cadr nach))
|
||||
(cons "FROM_TRO" (caddr von))
|
||||
(cons "TO_TRO" (caddr nach))
|
||||
(cons "KIND" "flow")))
|
||||
(entupd ent-neu)
|
||||
|
||||
(princ (ssg-textf "con-eingefuegt"
|
||||
(list (caddr von) (caddr nach) neue-id)))
|
||||
(ssg-end)
|
||||
(princ)
|
||||
)
|
||||
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; C:CONNECTION_EDIT - Quelle/Ziel einer Verbindung aendern
|
||||
;; ------------------------------------------------------------
|
||||
(defun c:CONNECTION_EDIT ( / ss ent ed bname
|
||||
alt-from-id alt-to-id alt-from alt-to alt-kind
|
||||
neu-from-id neu-to-id neu-from neu-to
|
||||
dcl-pfad dat ergebnis)
|
||||
|
||||
;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf)
|
||||
(setq ss (ssget "I"))
|
||||
(if (and ss (= (sslength ss) 1)
|
||||
(= (cdr (assoc 0 (entget (ssname ss 0)))) "INSERT"))
|
||||
(setq ent (ssname ss 0))
|
||||
)
|
||||
|
||||
(ssg-start "CONNECTION_EDIT" nil)
|
||||
|
||||
(if (null ent)
|
||||
(progn
|
||||
(princ (ssg-text "cmd-block-auswaehlen"))
|
||||
(setq ss (ssget ":S" '((0 . "INSERT"))))
|
||||
(if ss (setq ent (ssname ss 0)))
|
||||
)
|
||||
)
|
||||
(if (null ent)
|
||||
(progn (princ (ssg-text "cmd-kein-block-ausgewaehlt")) (ssg-end) (exit))
|
||||
)
|
||||
|
||||
(setq ed (entget ent)
|
||||
bname (cdr (assoc 2 ed)))
|
||||
(if (not (wcmatch bname "CONNECTION_*"))
|
||||
(progn
|
||||
(alert (ssg-textf "con-keine-verbindung" (list bname)))
|
||||
(ssg-end)
|
||||
(exit)
|
||||
)
|
||||
)
|
||||
|
||||
(setq alt-from-id (con-attrib ent "FROM_ID")
|
||||
alt-to-id (con-attrib ent "TO_ID")
|
||||
alt-from (con-attrib ent "FROM_TRO")
|
||||
alt-to (con-attrib ent "TO_TRO")
|
||||
alt-kind (con-attrib ent "KIND"))
|
||||
|
||||
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/connection_edit.dcl"))
|
||||
(setq dat (load_dialog dcl-pfad))
|
||||
(if (not (new_dialog "connection_edit" dat))
|
||||
(progn
|
||||
(alert (ssg-textf "con-dialog-fehlt" (list dcl-pfad)))
|
||||
(ssg-end)
|
||||
(exit)
|
||||
)
|
||||
)
|
||||
|
||||
(set_tile "blockname" (ssg-textf "con-block" (list bname (con-attrib ent "ID"))))
|
||||
(set_tile "from_id" alt-from-id)
|
||||
(set_tile "from_tro" alt-from)
|
||||
(set_tile "to_id" alt-to-id)
|
||||
(set_tile "to_tro" alt-to)
|
||||
(set_tile "richtung" (ssg-textf "con-richtung" (list alt-from alt-to)))
|
||||
(set_tile "hinweis" (ssg-text "con-hinweis"))
|
||||
|
||||
(setq neu-from-id alt-from-id neu-to-id alt-to-id
|
||||
neu-from alt-from neu-to alt-to)
|
||||
|
||||
(action_tile "from_id" "(setq neu-from-id (get_tile \"from_id\"))")
|
||||
(action_tile "to_id" "(setq neu-to-id (get_tile \"to_id\"))")
|
||||
(action_tile "from_tro" "(setq neu-from (get_tile \"from_tro\"))")
|
||||
(action_tile "to_tro" "(setq neu-to (get_tile \"to_tro\"))")
|
||||
(action_tile "accept"
|
||||
(strcat "(setq neu-from-id (get_tile \"from_id\")"
|
||||
" neu-to-id (get_tile \"to_id\")"
|
||||
" neu-from (get_tile \"from_tro\")"
|
||||
" neu-to (get_tile \"to_tro\"))"
|
||||
"(done_dialog 1)"))
|
||||
(action_tile "cancel" "(done_dialog 0)")
|
||||
|
||||
(setq ergebnis (start_dialog))
|
||||
(unload_dialog dat)
|
||||
|
||||
(if (= ergebnis 1)
|
||||
(if (or (= (vl-string-trim " " neu-from-id) "")
|
||||
(= (vl-string-trim " " neu-to-id) ""))
|
||||
(alert (ssg-text "con-id-leer"))
|
||||
(if (= neu-from-id neu-to-id)
|
||||
(alert (ssg-text "con-gleiche-id"))
|
||||
(progn
|
||||
(ssg-attrib-set-on ent
|
||||
(list (cons "FROM_ID" neu-from-id)
|
||||
(cons "TO_ID" neu-to-id)
|
||||
(cons "FROM_TRO" neu-from)
|
||||
(cons "TO_TRO" neu-to)
|
||||
(cons "KIND" (if (= alt-kind "") "flow" alt-kind))))
|
||||
(entupd ent)
|
||||
(princ (ssg-textf "con-gespeichert" (list neu-from neu-to)))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(ssg-end)
|
||||
(princ)
|
||||
)
|
||||
|
||||
|
||||
(prompt "\nConnection_Edit.lsp geladen - Befehle: CONNECTION_INSERT, CONNECTION_EDIT")
|
||||
(princ)
|
||||
@@ -439,6 +439,23 @@
|
||||
(c:VARIOFOERDERER_EDIT)
|
||||
)
|
||||
|
||||
;; Verbindungen (CONNECTION_*) -> CONNECTION_EDIT (DCL-Dialog)
|
||||
;; Vor der TRO-Pruefung, da beide aus der Beschriftung von sps_skel stammen
|
||||
;; und sich die Namensmuster nicht ueberschneiden duerfen.
|
||||
((wcmatch bname "CONNECTION_*")
|
||||
(princ (ssg-textf "cmd-connection-bearbeiten" (list bname)))
|
||||
(if (and (null *ssg-Connection_Edit-loaded*) (atoms-family 1 '("SSG-ENSURE")))
|
||||
(ssg-ensure "Connection_Edit")
|
||||
)
|
||||
(if (atoms-family 1 '("C:CONNECTION_EDIT"))
|
||||
(c:CONNECTION_EDIT)
|
||||
(progn
|
||||
(princ (ssg-textf "tro-edit-modul-fehlt" (list "Connection_Edit.lsp")))
|
||||
(command "_.EATTEDIT")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; TRO-Marker (TRO_SYM_<Typ>) -> TRO_EDIT (DCL-Dialog)
|
||||
;; Die Marker kommen aus sps_skel (lib/tro_annotate.py) und tragen die
|
||||
;; Attribute ID und TYPE. Modul bei Bedarf nachladen, damit der Doppelklick
|
||||
|
||||
+5
-3
@@ -245,7 +245,7 @@
|
||||
;; C:TRO_EDIT - Dialog fuer einen TRO-Marker
|
||||
;; ------------------------------------------------------------
|
||||
(defun c:TRO_EDIT ( / ss ent ed bname attribs
|
||||
alt-id alt-type alt-fb
|
||||
alt-id alt-type alt-fb int-id
|
||||
neu-id neu-type
|
||||
liste idx dcl-pfad dat ergebnis)
|
||||
|
||||
@@ -284,7 +284,8 @@
|
||||
(setq attribs (ssg-attrib-read ent)
|
||||
alt-id (cdr (assoc "ID" attribs))
|
||||
alt-type (cdr (assoc "TYPE" attribs))
|
||||
alt-fb (cdr (assoc "FB_BLOCK" attribs)))
|
||||
alt-fb (cdr (assoc "FB_BLOCK" attribs))
|
||||
int-id (cdr (assoc "UID" attribs)))
|
||||
|
||||
(if (null alt-id)
|
||||
(progn
|
||||
@@ -310,7 +311,8 @@
|
||||
idx (tro-index alt-type liste))
|
||||
|
||||
(set_tile "blockname" (ssg-textf "tro-edit-block" (list bname)))
|
||||
(set_tile "fb" (ssg-textf "tro-edit-fb" (list (if alt-fb alt-fb "-"))))
|
||||
(set_tile "fb" (ssg-textf "tro-edit-fb"
|
||||
(list (if alt-fb alt-fb "-") (if int-id int-id "-"))))
|
||||
(set_tile "hinweis" (ssg-text "tro-edit-hinweis"))
|
||||
(set_tile "id" alt-id)
|
||||
(start_list "type")
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
(load (strcat base-path "tests.lsp") "tests.lsp nicht gefunden")
|
||||
(load (strcat base-path "OmniModulInsert.lsp") "OmniModulInsert.lsp nicht gefunden")
|
||||
(load (strcat base-path "Tro_Edit.lsp") "Tro_Edit.lsp nicht gefunden")
|
||||
(load (strcat base-path "Connection_Edit.lsp") "Connection_Edit.lsp nicht gefunden")
|
||||
(load (strcat base-path "SSG_LIB_Commands.lsp") "SSG_LIB_Commands.lsp nicht gefunden")
|
||||
(prompt "\nSSG-Bibliotheken geladen: ssg_core, ssg_lang, ssg_dbg, ssg_dialog, ssg_layer, KreiselInsert, VarioFoerderer, Gefaellestrecke, export, tests, OmniModulInsert, SSG_LIB_Commands")
|
||||
(princ)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// ============================================================
|
||||
// connection_edit.dcl - Verbindung zwischen zwei TROs bearbeiten
|
||||
// Aendert Quelle und Ziel eines CONNECTION_*-Blocks. Gearbeitet wird
|
||||
// mit den internen IDs; die sprechenden Namen stehen daneben.
|
||||
// Aufruf ueber c:CONNECTION_EDIT (Lisp/Connection_Edit.lsp).
|
||||
// ============================================================
|
||||
|
||||
connection_edit : dialog {
|
||||
label = "Verbindung bearbeiten";
|
||||
|
||||
: column {
|
||||
|
||||
: text {
|
||||
key = "blockname";
|
||||
label = "";
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Quelle";
|
||||
: edit_box {
|
||||
key = "from_id";
|
||||
label = "Interne ID:";
|
||||
edit_width = 12;
|
||||
}
|
||||
: edit_box {
|
||||
key = "from_tro";
|
||||
label = "TRO-Kennung:";
|
||||
edit_width = 24;
|
||||
}
|
||||
}
|
||||
|
||||
: boxed_column {
|
||||
label = "Ziel";
|
||||
: edit_box {
|
||||
key = "to_id";
|
||||
label = "Interne ID:";
|
||||
edit_width = 12;
|
||||
}
|
||||
: edit_box {
|
||||
key = "to_tro";
|
||||
label = "TRO-Kennung:";
|
||||
edit_width = 24;
|
||||
}
|
||||
}
|
||||
|
||||
: text {
|
||||
key = "richtung";
|
||||
label = "";
|
||||
}
|
||||
|
||||
: text {
|
||||
key = "hinweis";
|
||||
label = "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ok_cancel;
|
||||
}
|
||||
+686
-670
File diff suppressed because it is too large
Load Diff
+686
-670
File diff suppressed because it is too large
Load Diff
@@ -130,6 +130,10 @@
|
||||
[Marker einfuegen]^C^C(ssg-ensure "Tro_Edit") TRO_INSERT
|
||||
[Marker bearbeiten]^C^C(ssg-ensure "Tro_Edit") TRO_EDIT
|
||||
[<-Bearbeiten (Auto)]^C^C(ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT
|
||||
[->Connections]
|
||||
[Verbindung einfuegen]^C^C(ssg-ensure "Connection_Edit") CONNECTION_INSERT
|
||||
[Verbindung bearbeiten]^C^C(ssg-ensure "Connection_Edit") CONNECTION_EDIT
|
||||
[<-Bearbeiten (Auto)]^C^C(ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT
|
||||
[->Export]
|
||||
[Export Sivas]^C^C(ssg-ensure "count_sep_scan") ZAEHLE_SEP_SCAN (ssg-ensure "export") EXPORTSIVAS
|
||||
[<-Export CSV]^C^C(ssg-ensure "export") EXPORTCSV
|
||||
@@ -167,5 +171,6 @@
|
||||
[Gefaellestrecke bearbeiten](ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_EDIT
|
||||
[VarioFoerderer bearbeiten](ssg-ensure "VarioFoerderer") VARIOFOERDERER_EDIT
|
||||
[TRO-Marker bearbeiten](ssg-ensure "Tro_Edit") TRO_EDIT
|
||||
[Verbindung bearbeiten](ssg-ensure "Connection_Edit") CONNECTION_EDIT
|
||||
[--]
|
||||
[SSG Bearbeiten (Auto)](ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT
|
||||
|
||||
Reference in New Issue
Block a user