[CHANGE] Lager-JSON: null nur fuer fehlende Werte, Regalrohr statt SCHIENEN, Plausibilitaetswarnungen

This commit is contained in:
Simon Hensch committed 2026-11-04 07:49:51 +01:00
1 parent d2729140ff
commit a20049a248
9 files changed
+433 -130

No files matched your search

+1 -1
View File
@@ -125,7 +125,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`.
| `KettenFoerderer.lsp` | KETTENFOERDERER, KF_EDIT, KF_KS_PRUEFEN | Kettenfoerderer/Schraegfoerderer Stahl: baut aus `KF_UM_<winkel>` -> `KF_LAENGE` -> `KF_AN_<winkel>` (je KS_AUS auf KS_EIN) plus der Draufsicht `KF_2D` EINEN Block `KF_<n>`. Daten `data/json/kettenfoerderer.json`, Dialog `dcl/kettenfoerderer.dcl`. **Geometrie**: SEITENANSICHT in der XY-Ebene (Hoehe = Y), ungedreht und nicht aufgerichtet, Einfuegepunkt = KS_EIN der Umlenkung; jeder Baustein bekommt nur den aus den KS gemessenen Verkettungswinkel (`insert-block-by-ks`/`insert-block-ks-skaliert`). Die Neigung (26/30 Grad) ist KEIN Rechenparameter: sie steckt in den Varianten-Bloecken, der Einbauwinkel jedes Folgebausteins wird zur Laufzeit aus der RICHTUNG des KS_AUS seines Vorgaengers gemessen (`ks-xy-winkel`/`kf-hz-folge`) - keine gepflegte Winkeltabelle. `KF_LAENGE` wird in X skaliert, die Einbauhoehe H bestimmt seine Laenge ueber die Hoehenbilanz (`kf-laenge-berechnen`). **Hauptblock + Hilfsblock**: `KF_<n>` traegt Beschriftung (`KF_1 26 Grad H=..mm L_horizontal=..mm`, Layer `kettenfoerderer_beschriftung`) und ein Hoehenmass (ActiveX `AddDimRotated`, scheitert es, wird ohne Mass gebaut) und ist der EINZIGE exportierte Block. Die Draufsicht `KF_2D` ist ein getrennter Hilfsblock `KF2D_<n>` (kein Objekt, nur zum Anschliessen von Schienen): flach, auf die PROJIZIERTE Laenge skaliert (`kf-waagerecht-laenge`), beim ersten Einfuegen `ansicht_2d.versatz_y` (-1000) mm unter dem Hauptblock, danach frei verschieb- und loeschbar, gleiche Beschriftung. Beide Bloecke tragen denselben Schluessel als XDATA `SSG_KF_EDIT` (`kf-xdata-key`); KF_EDIT findet damit den - auch verschobenen - Hilfsblock (`kf-hilfsblock-finden`), behaelt dessen Lage und erzeugt ihn bei jedem Edit neu (auch wenn er geloescht war). Der Hilfsblock passt nicht aufs Export-Muster `KF_*`; `export_sivas.py` nimmt ausserdem nur `KF_<Ziffern>`. Eine von Hand gesetzte Drehung des Hauptblocks (DXF 50) wird beim Edit wieder aufgesetzt. **Attribut-Schema** `*kf-attrib-defs-liste*` ist EIGENSTAENDIG und bewusst NICHT von `ssg-strecke-attrib-defs` abgeleitet (sonst ~24 geerbte VF-Tags am Block); die Reihenfolge folgt dem Sivas-Merkmalstamm. FOERDERERTYP = Bauart im Klartext, WINKEL = nackte Zahl 26/30 (der Klartext mit Gradzeichen entsteht erst ueber `[kf_typ_anzeige]` in cfg/sivas.cfg, damit Attributwerte ASCII bleiben); kein TEILEART (Festwert `KF_TEILEART` im Export). `L_KF_mm` ist die WAAGERECHTE Laenge des ganzen Foerderers (der Draufsicht `KF_2D`, `kf-waagerecht-laenge`), nicht die Laenge des schraegen Mittelstuecks; sie geht NICHT in die Sivas-Zeile (Spalte Laenge bleibt leer) - Sivas berechnet ZL, EL und Kettenlaenge selbst, uebernommen wird nur die Hoehe (360). Alle Auswahllisten stehen mit ihren Sivas-Optionstexten in der JSON. **Das `KF_`-Praefix ist wie `GR_` nicht kosmetisch**: `SSG_BLOCKEDIT` haelt JEDEN Block mit TEILEART-Attribut fuer ein Omniflo-Element, darum steht ein `KF_*`-Zweig VOR dem Omniflo-Zweig (Doppelklick -> KF_EDIT, der die vorgewaehlte Auswahl nutzt und nur echte `KF_<n>` zulaesst - die Bausteine `KF_UM_26`, `KF_2D` usw. tragen dasselbe Praefix). **Die Blocknummer wird ueber die Blocktabelle vergeben** (`kf-naechste-nummer` ueberspringt jede Nummer mit vorhandener Block-DEFINITION, wie bei `GF_n`/`VF_n`): nur ueber die Referenzen im Modell zu zaehlen war ein realer Fehler - `KF_EDIT` loescht den alten Block, die Definition lebt aber weiter, `_.-BLOCK` traf auf den vorhandenen Namen, die "Neu definieren?"-Abfrage verschluckte die Folge-Eingaben, und die Einzelteile blieben lose liegen ("Block aufgeloest"). **Sivas-Export** (`[kettenfoerderer]` in cfg/sivas.cfg, `build_kettenfoerderer_details` in export_sivas.py): baugleiche Foerderer werden zu EINER Zeile zusammengefasst (`kettenfoerderer_signature`), die Gruppengroesse traegt Merkmal 353 (entsteht erst aus der Gruppierung, daher Code); Farbe (354) und Antriebsmotor (355) sind ZWEI Merkmale, und jedes merkmalbildende Attribut steht auch in der Signatur, sonst verschmelzen unterschiedlich ausgefuehrte Foerderer. Reine Kerne in `tests/test_unit.lsp` (`tu-tests-kf`); das Modul wird in der MNL vorgeladen, Laufzeit-Messung ueber den dbg-Schalter `kf-zeit` |
| `HwPlanung.lsp` | HW_MATERIALFLUSS, HW_SYMBOLE | Menue "HW Planung" (zwischen Lager und SPS). HW_MATERIALFLUSS ruft EXPORTCSV auf (alte `<dwg>_export.csv` wird vorher geloescht, damit kein veralteter Stand gezeichnet wird) und danach `lib/hw_materialfluss.py` ueber `export:run-python` (Log `DXFM_LOG/hw_materialfluss.log`); Ergebnis ist eine NEUE Datei `DXFM_RESULTS/<dwg>_HW.dxf` (`hw-dxf-name`, getestet), die offene Zeichnung bleibt unveraendert. HW_SYMBOLE ist noch ein Platzhalter (Hinweis) |
| `menu-inventory.lsp` | MenuInventory | BricsCAD Diagnostik (Menuegruppen, Plugins, Startdateien) |
| `LagerInsert.lsp` | LG_GESCHOSS, LG_GESCHOSS_AKTIV, LG_GESCHOSS_KOPIEREN, LG_BEREICH, LG_REIHE, LG_GANG, LG_EDIT, LG_REGALE, LAGER_EXPORT | Lagerplanung GOH-Buehnenlager -> technische Daten als JSON fuer die RFQ-Dokumentation (Phase 0+1: Mengen, 2D; Konzept/Schema/Kennwerte in `doc/plan/lager_rfq.md`). Bloecke `LG_GESCHOSS` (Kopfsymbol, XDATA `SSG_LG` `kontur` -> Belagskontur), `LG_BEREICH` (Kontur + Parameter, fuellt sich selbst), `LG_REIHE_<L>_<T>`/`LG_GANG_<L>_<B>_<BELAG>` (Definition je Geometrie wiederverwendet, Werte in den Attributen der Referenz; Kinder tragen XDATA `bereich`; der Belag steht im Gang-Blocknamen, weil die Definition seine Schraffur enthaelt - Muster aus `lager.json belag_schraffur`, per `vla-AddHatch` auf Layer 0/VONBLOCK, `hallenboden` ohne; BricsCAD-`iso.pat` kennt kein `NET`, Gitterrost = `GRID`). Alle tragen `ID`, `GESCHOSS`, `LAYER`. Blockdefinitionen per `entmake` (BLOCK...ENDBLK), Einfuegen per `vla-InsertBlock` in WCS - kein `_.-BLOCK`/`_.INSERT`. **Attribut-Tags haben gemischte Schreibweise** (`HOEHE_BELAG_mm`) - beim Setzen ueber `vla-get-TagString` daher case-insensitiv zuordnen (`lg-wert-fuer-tag`), sonst bleiben diese Attribute still leer (realer Fehler beim Bau). Layer je Geschoss = Basis aus `cfg/layer.cfg [lager]` + `_G<nr>`; `LG_GESCHOSS_AKTIV` friert die uebrigen (2D-Grundrisse liegen uebereinander), aktives Geschoss als `vlax-ldata` (Dictionary `SSG_LAGER`). Geschosszuordnung `lg-geschoss-fuer-punkt-kern`: eine Kontur -> eindeutig, mehrere nur ueber Z unterscheidbar, wenn die Konturen auf verschiedenen Hoehen liegen (3D), sonst nil. Jede Kontur gehoert genau einem Block (vergebene Kontur wird kopiert). Auto-Fuellung `lg-fuellung-berechnen` (reiner Kern, Muster Reihe|Gang|Reihe Ruecken an Ruecken bzw. Reihe|Gang, nur volle Module, Streifen an Unter-/Mittel-/Oberkante gegen die Kontur geschnitten, Quergaenge ausgerichtet und nicht am Reihenende); Bereichs-Edit = Neuaufbau aller Kinder. **Randgaenge** `RANDGANG_N/O/S/W_mm` (Nord = +Y Welt) laufen entlang der echten Konturkanten (`lg-randgang-streifen`, Himmelsrichtung der Aussennormale ueber `lg-kompass`, auch L-Form; Ecken: N/S besitzen sie - konvex O/W kuerzen, einspringend N/S verlaengern) und werden wie manuelle Gaenge (`LG_GANG`, `QUELLE=manuell`, Kern `lg-gang-einfuegen`; per Linie oder Option `Rechteck` = Flaeche mit dem echten BricsCAD-Befehl RECHTECK gezeichnet, inkl. aller seiner Optionen (`lg-rechteck-zeichnen`: `_.RECTANG` + `(command pause)`-Schleife bei CMDECHO 1, Polylinie danach ueber `lg-rechteck-ecken-aus-poly` gelesen und geloescht; nur 4 Ecken ohne Boegen, sonst Meldung), Breite/Lage aus dem Rechteck ueber `lg-gang-aus-ecken`, Schleife `lg-linien-schleife` mit `rechteck-fn`) als **Sperrflaechen** aus Reihen/Haupt-/Quergaengen ausgeschnitten (`ssg-poly-band-x`). **Von Hand Gesetztes loest KEINE Neuberechnung aus**: `LG_REIHE`/`LG_GANG` (`lg-manuell-einfuegen`) und das Bearbeiten einer Reihe/eines Gangs (`lg-linie-neu-aufbauen-sperre`) schneiden nur die eigene Flaeche aus den rangniedrigeren Objekten heraus (`lg-sperre-anwenden`, reiner Kern `lg-linie-zuschnitt`; Rang `lg-quelle-rang`: auto < auto_geaendert < manuell) - frueher fuellte ein manueller Gang den ganzen Bereich neu, dabei kamen geloeschte Objekte zurueck und geaenderte wurden ersetzt. Die ausdrueckliche Neuberechnung (`lg-bereich-fuellen`, Bereich bearbeiten) entfernt nur `QUELLE=auto`; `manuell`/`auto_geaendert`-Kinder und unverknuepfte manuelle Objekte in der Kontur (`lg-manuelle-in-kontur`) bleiben und sperren ihre Flaeche. `lg-blockdef` ergaenzt bei Altbestand fehlende ATTDEFs (Neudefinition + `_.ATTSYNC`). `LAGER_EXPORT` schreibt NUR `<dwg>_lager.json` nach `DXFM_RESULTS` (Format `ssg-lager` Version 2, kein Python-Schritt; das RFQ-Projekt uebernimmt Mapping und Hand-Abgleich): alle Geschosse, Bereiche, Reihen und Gaenge mit Attributen und voller Geometrie (Konturpunkte, Start/Ende/Mitte, 4 Ecken) plus `kennwerte` je Geschoss und `lager` gesamt (lichte Hoehe, Regal-/Schienenlaenge, Haengeebenen, Gaenge je Art, Belags-/Gitterrostflaeche, Gitterkorb), je Geschoss-Kennwert `herkunft` (Formel + Quelle). Eigener JSON-Schreiber `lg-json-*` ueber getaggte Werte `(OBJ ...)`/`(ARR ...)` (`lg-json-text` rueckt ein, Nicht-ASCII als `\uXXXX`), Kennwerte in reinen Kernen (`lg-kennwerte-geschoss`/`-lager`, `lg-haengeebenen-summen`, `lg-gaenge-je-art`, `lg-reihen-offene-kanten`, `lg-reihen-gitterkorb-berechnen`). **Absturzsicherung unter den Reihen** je Bereich (`UNTER_REIHE` = `gitterrost`/`gitterkorb`/`keine`, Vorgabe `lager.json bereich.unter_reihe`, nur auf Buehnen wirksam): Gitterrost zaehlt die Reihengrundflaeche zur Gitterrostflaeche, Gitterkorb liefert Boden (Laenge x Tiefe) und Seitenflaeche = OFFENE Kantenlaenge x `GITTERKORB_HOEHE_mm` (Kanten an einer direkt anliegenden Nachbarreihe desselben Geschosses, z.B. Ruecken an Ruecken, zaehlen nicht; die Korbhoehe soll spaeter aus den Attributen berechnet werden). Regelwerk-Werte stehen noch Line truncated
| `LagerInsert.lsp` | LG_GESCHOSS, LG_GESCHOSS_AKTIV, LG_GESCHOSS_KOPIEREN, LG_BEREICH, LG_REIHE, LG_GANG, LG_EDIT, LG_REGALE, LAGER_EXPORT | Lagerplanung GOH-Buehnenlager -> technische Daten als JSON fuer die RFQ-Dokumentation (Phase 0+1: Mengen, 2D; Konzept/Schema/Kennwerte in `doc/plan/lager_rfq.md`). Bloecke `LG_GESCHOSS` (Kopfsymbol, XDATA `SSG_LG` `kontur` -> Belagskontur), `LG_BEREICH` (Kontur + Parameter, fuellt sich selbst), `LG_REIHE_<L>_<T>`/`LG_GANG_<L>_<B>_<BELAG>` (Definition je Geometrie wiederverwendet, Werte in den Attributen der Referenz; Kinder tragen XDATA `bereich`; der Belag steht im Gang-Blocknamen, weil die Definition seine Schraffur enthaelt - Muster aus `lager.json belag_schraffur`, per `vla-AddHatch` auf Layer 0/VONBLOCK, `hallenboden` ohne; BricsCAD-`iso.pat` kennt kein `NET`, Gitterrost = `GRID`). Alle tragen `ID`, `GESCHOSS`, `LAYER`. Blockdefinitionen per `entmake` (BLOCK...ENDBLK), Einfuegen per `vla-InsertBlock` in WCS - kein `_.-BLOCK`/`_.INSERT`. **Attribut-Tags haben gemischte Schreibweise** (`HOEHE_BELAG_mm`) - beim Setzen ueber `vla-get-TagString` daher case-insensitiv zuordnen (`lg-wert-fuer-tag`), sonst bleiben diese Attribute still leer (realer Fehler beim Bau). Layer je Geschoss = Basis aus `cfg/layer.cfg [lager]` + `_G<nr>`; `LG_GESCHOSS_AKTIV` friert die uebrigen (2D-Grundrisse liegen uebereinander), aktives Geschoss als `vlax-ldata` (Dictionary `SSG_LAGER`). Geschosszuordnung `lg-geschoss-fuer-punkt-kern`: eine Kontur -> eindeutig, mehrere nur ueber Z unterscheidbar, wenn die Konturen auf verschiedenen Hoehen liegen (3D), sonst nil. Jede Kontur gehoert genau einem Block (vergebene Kontur wird kopiert). Auto-Fuellung `lg-fuellung-berechnen` (reiner Kern, Muster Reihe|Gang|Reihe Ruecken an Ruecken bzw. Reihe|Gang, nur volle Module, Streifen an Unter-/Mittel-/Oberkante gegen die Kontur geschnitten, Quergaenge ausgerichtet und nicht am Reihenende); Bereichs-Edit = Neuaufbau aller Kinder. **Randgaenge** `RANDGANG_N/O/S/W_mm` (Nord = +Y Welt) laufen entlang der echten Konturkanten (`lg-randgang-streifen`, Himmelsrichtung der Aussennormale ueber `lg-kompass`, auch L-Form; Ecken: N/S besitzen sie - konvex O/W kuerzen, einspringend N/S verlaengern) und werden wie manuelle Gaenge (`LG_GANG`, `QUELLE=manuell`, Kern `lg-gang-einfuegen`; per Linie oder Option `Rechteck` = Flaeche mit dem echten BricsCAD-Befehl RECHTECK gezeichnet, inkl. aller seiner Optionen (`lg-rechteck-zeichnen`: `_.RECTANG` + `(command pause)`-Schleife bei CMDECHO 1, Polylinie danach ueber `lg-rechteck-ecken-aus-poly` gelesen und geloescht; nur 4 Ecken ohne Boegen, sonst Meldung), Breite/Lage aus dem Rechteck ueber `lg-gang-aus-ecken`, Schleife `lg-linien-schleife` mit `rechteck-fn`) als **Sperrflaechen** aus Reihen/Haupt-/Quergaengen ausgeschnitten (`ssg-poly-band-x`). **Von Hand Gesetztes loest KEINE Neuberechnung aus**: `LG_REIHE`/`LG_GANG` (`lg-manuell-einfuegen`) und das Bearbeiten einer Reihe/eines Gangs (`lg-linie-neu-aufbauen-sperre`) schneiden nur die eigene Flaeche aus den rangniedrigeren Objekten heraus (`lg-sperre-anwenden`, reiner Kern `lg-linie-zuschnitt`; Rang `lg-quelle-rang`: auto < auto_geaendert < manuell) - frueher fuellte ein manueller Gang den ganzen Bereich neu, dabei kamen geloeschte Objekte zurueck und geaenderte wurden ersetzt. Die ausdrueckliche Neuberechnung (`lg-bereich-fuellen`, Bereich bearbeiten) entfernt nur `QUELLE=auto`; `manuell`/`auto_geaendert`-Kinder und unverknuepfte manuelle Objekte in der Kontur (`lg-manuelle-in-kontur`) bleiben und sperren ihre Flaeche. `lg-blockdef` ergaenzt bei Altbestand fehlende ATTDEFs (Neudefinition + `_.ATTSYNC`). `LAGER_EXPORT` schreibt NUR `<dwg>_lager.json` nach `DXFM_RESULTS` (Format `ssg-lager` Version 2, kein Python-Schritt; das RFQ-Projekt uebernimmt Mapping und Hand-Abgleich): alle Geschosse, Bereiche, Reihen und Gaenge mit Attributen und voller Geometrie (Konturpunkte, Start/Ende/Mitte, 4 Ecken) plus `kennwerte` je Geschoss und `lager` gesamt (lichte Hoehe, Regal-/Schienenlaenge, Haengeebenen, Gaenge je Art und Breite, Belags-/Gitterrostflaeche, Gitterkorb, Regalrohr = Laenge x Haengeebenen), je Geschoss-Kennwert `herkunft` (Formel + Quelle). **`null` = fehlt (offener Punkt), nicht Zutreffendes wird weggelassen** (Marker `'ENTFAELLT`, `lg-json-ohne-entfallend`). Plausibilitaetswarnungen je Geschoss (`lg-plausibilitaet`, Grenzwerte aus dem Regelprofil). Das Reihen-Attribut `SCHIENEN` ist entfallen; `SCHIENEN_JE_GANG` am Bereich (Trolley) wird noch nicht ausgewertet. Eigener JSON-Schreiber `lg-json-*` ueber getaggte Werte `(OBJ ...)`/`(ARR ...)` (`lg-json-text` rueckt ein, Nicht-ASCII als `\uXXXX`), Kennwerte in reinen Kernen (`lg-kennwerte-geschoss`/`-lager`, `lg-haengeebenen-summen`, `lg-gaenge-je-art`, `lg-reihen-offene-kanten`, `lg-reihen-gitterkorb-berechnen`). **Absturzsicherung unter den Reihen** je Bereich (`UNTER_REIHE` = `gitterrost`/`gitterkorb`/`keine`, Vorgabe `lager.json bereich.unter_reihe`, nur auf Buehnen wirksam):Line truncated
| `LagerPruefung.lsp` | LG_REGELN | Regelprofile der Lagerplanung: `cfg/stahlbau/regelwerk/<LAND>.json` laden, `erbt_von` aufloesen (`lg-profil-mischen`), je Regel den STRENGSTEN Wert aller zutreffenden Quellen (`lg-regel-aufloesen`: `art` min/max/wert, `bedingung` gegen einen Kontext - fehlt der Schluessel, konservativ einbezogen -, `tabelle` + `tabellen_schluessel`) mit Protokoll. Jede Pruefregel der Lagerplanung wird genau hier implementiert (Python rendert nur). Alle Startwerte `verifiziert: false` |
| `DinFormate.lsp` | DIN_FORMATE | Ersatz fuer das alte ACADSST-Makro `DINFORM.LSP`/`.DCL` (SSG2-Menue "DIN-FORMATE..."): fuegt einen DIN-Rahmen (A0-A3, A4 quer/hoch) und optional einen Schriftkopf (KOPF11, Sprachen DE/EN/FR/IT) per Dialog (`dcl/dinformate.dcl`) ein. Block-DWGs liegen flach in `cfg/rahmen/` (kopiert aus `\\infor-ln\SSG_Tools\ACADSST\KOEPFE` - nur die von DINFORM.LSP tatsaechlich referenzierten Dateien: `A0`/`A1`/`A2`/`A3`/`A4Q`/`A4H.DWG` + `Kopf11`/`Kopf11e`/`Kopf11f`/`Kopf11i.dwg`). Rahmen wird im Zeichenmassstab-Faktor eingefuegt, der Kopf im Faktor/100 (Kopf-DWG ist 100x groesser als die Rahmen-DWGs angelegt) - unveraendert aus dem Original-Massstabsschema uebernommen. Blockdefinitionen werden einmalig per `_.-INSERT ... _X 0` nachgeladen (`dinformate-block-laden`), falls noch nicht in der Zeichnung vorhanden. Lazy geladen ueber `(ssg-ensure "DinFormate")`, Menue: Werkzeuge > Din Formate. |
| `DrawPlanquadrate.lsp` | DRAW_PLANQUADRATE, DELETE_PLANQUADRATE, PLANQUADRATE_TOGGLE | Zeichnet auf Z=0 ein Planquadrat-Linienraster (senkrecht/waagerecht), im Abstand/Zaehlschema der aktiven `[Planquadrate]`-Konfiguration aus `cfg/export.cfg` (dieselbe Quelle wie `lib/export_planquadrat.py` fuer den CSV-Export). Bereich kommt NICHT aus den Zeichnungs-Extents, sondern aus derselben Blockmenge wie EXPORTCSV (`csv:collect-export-blocks`, export.lsp; siehe `plq-export-bbox`): Ursprung (Index 1) UND obere Grenze kommen BEIDE aus der tatsaechlichen Bounding-Box jedes Blocks (`csv:get-bbox`, wie `bbox_columns()`/`planquadrat_column()`/`_bbox_min()` in `lib/export_csv.py` bzw. `lib/export_planquadrat.py`), NICHT aus dem reinen Einfuegepunkt - bei einem gedrehten/exzentrisch eingefuegten Block (z.B. ein um 90 Grad gedrehter Kreisel) kann das Bounding-Box-Zentrum weit vom Einfuegepunkt abweichen; Ursprung und Zellzuordnung muessen auf derselben Referenz beruhen, sonst driften sie auseinander (realer Bug, behoben). Reine Hilfsgeometrie (Kreisel-Umfahrungsboegen als eigene Linien, Texte) zaehlt bewusst nicht mit, sonst weicht das Raster vom CSV-Export ab. `x_origin`/`y_origin` ueberschreiben den Ursprung, Fallback auf EXTMIN/EXTMAX falls keine Export-Bloecke vorhanden sind bzw. `csv:get-bbox` fuer einen Block scheitert. Spalten-/Zeilenzahl wird IMMER aufgerundet auf volle Rasterschritte, damit alle senkrechten Linien auf der letzten waagerechten enden und umgekehrt - das Raster bildet immer ein geschlossenes Rechteck. Zaehlung (alphabetisch/numerisch je Achse) als Text am linken/unteren Rand. Das fertige Raster (Linien+Texte) wird per `_.-BLOCK`/`_.INSERT` zu einem einzigen Block `ZZ_PLANQUADRATE` bei (0,0,0) zusammengefasst. Layer aus `cfg/layer.cfg` (`[allgemein]` Key `planquadrate`, Fallback `ZZ_Planquadrate`). DRAW_PLANQUADRATE entfernt vor dem Neuaufbau zuerst einen evtl. vorhandenen Block (`plq-block-entfernen`: INSERTs loeschen + `_-PURGE _B`), DELETE_PLANQUADRATE ruft nur diese Entfernung auf. PLANQUADRATE_TOGGLE ("Planquadrate an/aus", Menue: Konfiguration) prueft per `tblsearch`/`ssget "X"`, ob der Block existiert, und dispatcht auf Zeichnen bzw. Loeschen. Lazy geladen ueber `(ssg-ensure "DrawPlanquadrate")`, nicht in der Core-Ladereihenfolge. Die Planquadrat-SPALTE im CSV-Export (`export_csv.py::planquadrat_column`/`resolve_origins`, `lib/export_planquadrat.py::compute_planquadrat`/`_bbox_min`) rechnet ebenfalls durchgaengig auf Bounding-Box-Basis (nicht nur Einfuegepunkt) und liefert eine SPANNE ("A/1-J/1") statt nur einer Zelle, wenn ein Element mehr als eine Zelle ueberdeckt (Kreisel, lange VF-/GF-Ketten). |
+276 -81
View File
@@ -384,7 +384,7 @@
(setq *lg-schema-reihe*
'(("ID" . "") ("GESCHOSS" . "") ("LAYER" . "") ("LAENGE" . "") ("TIEFE_mm" . "")
("HAENGEEBENEN" . "") ("SCHIENEN" . "") ("BEREICH" . "") ("QUELLE" . "")))
("HAENGEEBENEN" . "") ("BEREICH" . "") ("QUELLE" . "")))
(setq *lg-schema-gang*
'(("ID" . "") ("GESCHOSS" . "") ("LAYER" . "") ("LAENGE" . "") ("BREITE_mm" . "")
@@ -638,8 +638,7 @@
(setq *lg-felder-reihe*
'(("laenge" "LAENGE" "mm" nil)
("tiefe" "TIEFE_mm" "mm" nil)
("ebenen" "HAENGEEBENEN" "ebenen" nil)
("schienen" "SCHIENEN" "int0" nil)))
("ebenen" "HAENGEEBENEN" "ebenen" nil)))
;; LG_GESCHOSS_KOPIEREN - die Tags sind reine Dialogwerte, kein Block-Schema.
(setq *lg-felder-kopie*
@@ -1379,7 +1378,6 @@
(setq werte-reihe
(list (cons "GESCHOSS" gs) (cons "TIEFE_mm" (cdr (assoc "REGALTIEFE_mm" a)))
(cons "HAENGEEBENEN" (cdr (assoc "HAENGEEBENEN" a)))
(cons "SCHIENEN" (cdr (assoc "SCHIENEN_JE_GANG" a)))
(cons "BEREICH" (cdr (assoc "NR" a))) (cons "QUELLE" "auto")))
(foreach r (car erg)
(setq p1 (ssg-punkt-drehen (cadr r) w '(0.0 0.0))
@@ -1916,8 +1914,7 @@
(setq werte (lg-dialog "lg_reihe" *lg-felder-reihe*
(list (cons "LAENGE" "0")
(cons "TIEFE_mm" (lg-mm-str (lg-zahl (lg-vorgabe '("bereich" "regaltiefe_mm") 700))))
(cons "HAENGEEBENEN" (lg-vorgabe '("reihe" "haengeebenen") "2300/1200;1100/1100"))
(cons "SCHIENEN" (itoa (fix (lg-zahl (lg-vorgabe '("reihe" "schienen") 1))))))
(cons "HAENGEEBENEN" (lg-vorgabe '("reihe" "haengeebenen") "2300/1200;1100/1100")))
'("laenge")))
(if werte
(progn
@@ -2100,11 +2097,19 @@
(defun lg-json-obj (paare)
(strcat "{"
(ssg-join (mapcar '(lambda (p) (strcat (lg-json-str (car p)) ": " (lg-json-wert (cdr p)))) paare)
(ssg-join (mapcar '(lambda (p) (strcat (lg-json-str (car p)) ": " (lg-json-wert (cdr p))))
(lg-json-ohne-entfallend paare))
", ")
"}")
)
;; Regel fuer fehlende Werte: null = "fehlt, muesste eingegeben werden"
;; (offener Punkt fuer den Konsumenten); 'ENTFAELLT = "trifft hier nicht zu"
;; - solche Felder werden gar nicht geschrieben.
(defun lg-json-ohne-entfallend (paare)
(vl-remove-if '(lambda (p) (eq (cdr p) 'ENTFAELLT)) paare)
)
(defun lg-json-container-p (v)
(and v (listp v) (member (car v) '(OBJ ARR)))
)
@@ -2141,7 +2146,8 @@
(setq innen (strcat einr " ") obj-p (eq (car v) 'OBJ))
(setq zeilen
(if obj-p
(mapcar '(lambda (p) (strcat innen (lg-json-str (car p)) ": " (lg-json-text (cdr p) innen))) (cdr v))
(mapcar '(lambda (p) (strcat innen (lg-json-str (car p)) ": " (lg-json-text (cdr p) innen)))
(lg-json-ohne-entfallend (cdr v)))
(mapcar '(lambda (x) (strcat innen (lg-json-text x innen))) (cdr v))))
(if zeilen
(strcat (if obj-p "{" "[") "\n" (ssg-join zeilen ",\n") "\n" einr (if obj-p "}" "]"))
@@ -2150,7 +2156,12 @@
)
;; --- Zugriff auf OBJ-Records ---
(defun lg-j (obj key) (cdr (assoc key (cdr obj))))
;; Feld eines OBJ; nil, wenn es fehlt, ENTFAELLT ist oder obj kein OBJ ist.
(defun lg-j (obj key / v)
(if (and obj (listp obj) (eq (car obj) 'OBJ))
(progn (setq v (cdr (assoc key (cdr obj))))
(if (eq v 'ENTFAELLT) nil v)))
)
(defun lg-j-setzen (obj key wert / alt)
(if (setq alt (assoc key (cdr obj)))
@@ -2162,10 +2173,36 @@
(defun lg-j-bbox (bb) (if bb (cons 'ARR (append (car bb) (cadr bb)))))
(defun lg-n (v) (if (numberp v) (float v) 0.0))
;; Freiraum unter der Ware je Haengeebene (reiner Kern): Schienenhoehe -
;; Warenlaenge - naechsttiefere Schienenhoehe (unterste Ebene: - 0 = Belag).
;; ebenen = ((schienenhoehe warenlaenge) ...); Rueckgabe ((h w frei) ...),
;; nach Schienenhoehe absteigend. frei <= 0: Ware stoesst an.
(defun lg-ebenen-freiraum (ebenen / sort erg rest)
(setq sort (vl-sort ebenen '(lambda (a b) (> (car a) (car b)))) erg nil)
(while sort
(setq rest (cdr sort))
(setq erg (cons (list (car (car sort)) (cadr (car sort))
(- (car (car sort)) (cadr (car sort)) (if rest (car (car rest)) 0.0)))
erg)
sort rest))
(reverse erg)
)
(defun lg-j-ebenen (s)
(cons 'ARR
(mapcar '(lambda (e) (list 'OBJ (cons "schienenhoehe_mm" (car e)) (cons "warenlaenge_mm" (cadr e))))
(lg-haengeebenen-parse s)))
(mapcar '(lambda (e) (list 'OBJ (cons "schienenhoehe_mm" (car e)) (cons "warenlaenge_mm" (cadr e))
(cons "freiraum_unter_mm" (caddr e))))
(lg-ebenen-freiraum (lg-haengeebenen-parse s))))
)
;; Ausrichtung eines Gangs gegen die Reihenrichtung seines Bereichs (beide
;; in Grad): "laengs" (Abweichung < 45 Grad, Richtung egal) oder "quer";
;; nil ohne Reihenrichtung. Rein.
(defun lg-ausrichtung (winkel richtung / d)
(if (and (numberp winkel) (numberp richtung))
(progn
(setq d (rem (abs (- winkel richtung)) 180.0))
(if (< (min d (- 180.0 d)) 45.0) "laengs" "quer")))
)
;; Attributwert als Zahl bzw. Ganzzahl (nil, wenn leer).
@@ -2203,22 +2240,40 @@
(> (car (car a)) (car (car b))))))))
)
;; Gaenge je ART: (OBJ ("gang" . (OBJ anzahl laenge_mm flaeche_mm2)) ...),
;; gang/quergang/randgang immer vorhanden, weitere Arten dahinter.
(defun lg-gaenge-je-art (gaenge / erg art x l f)
(setq erg (mapcar '(lambda (a) (list a 0 0.0 0.0)) '("gang" "quergang" "randgang")))
;; Gaenge je ART: (OBJ ("gang" . (OBJ anzahl laenge_mm flaeche_mm2
;; anzahl_quer nach_breite)) ...), gang/quergang/randgang immer vorhanden,
;; weitere Arten dahinter. anzahl_quer = Gaenge mit ausrichtung "quer";
;; nach_breite = je Breite Anzahl/Laenge/Flaeche (Sonderflaechen erkennbar,
;; keine verfaelschte Durchschnittsbreite).
(defun lg-gaenge-je-art (gaenge / erg art x l b f br bx)
(setq erg (mapcar '(lambda (a) (list a 0 0.0 0.0 0 nil)) '("gang" "quergang" "randgang")))
(foreach g gaenge
(setq art (cond ((lg-j g "art")) ("unbekannt"))
x (assoc art erg)
(setq art (cond ((lg-j g "art")) ("unbekannt")))
(if (null (assoc art erg)) (setq erg (append erg (list (list art 0 0.0 0.0 0 nil)))))
(setq x (assoc art erg)
l (lg-n (lg-j g "laenge_mm"))
f (* l (lg-n (lg-j g "breite_mm"))))
(setq erg (if x
(subst (list art (1+ (cadr x)) (+ (caddr x) l) (+ (cadddr x) f)) x erg)
(append erg (list (list art 1 l f))))))
b (lg-n (lg-j g "breite_mm"))
f (* l b)
br (nth 5 x)
bx (assoc b br)
br (if bx
(subst (list b (1+ (cadr bx)) (+ (caddr bx) l) (+ (cadddr bx) f)) bx br)
(cons (list b 1 l f) br)))
(setq erg (subst (list art (1+ (nth 1 x)) (+ (nth 2 x) l) (+ (nth 3 x) f)
(+ (nth 4 x) (if (equal (lg-j g "ausrichtung") "quer") 1 0)) br)
x erg)))
(cons 'OBJ
(mapcar '(lambda (x) (cons (car x) (list 'OBJ (cons "anzahl" (cadr x))
(cons "laenge_mm" (caddr x))
(cons "flaeche_mm2" (cadddr x)))))
(mapcar '(lambda (x)
(cons (car x)
(list 'OBJ (cons "anzahl" (nth 1 x))
(cons "laenge_mm" (nth 2 x))
(cons "flaeche_mm2" (nth 3 x))
(cons "anzahl_quer" (nth 4 x))
(cons "nach_breite"
(cons 'ARR
(mapcar '(lambda (y) (list 'OBJ (cons "breite_mm" (car y)) (cons "anzahl" (cadr y))
(cons "laenge_mm" (caddr y)) (cons "flaeche_mm2" (cadddr y))))
(vl-sort (nth 5 x) '(lambda (a b) (< (car a) (car b))))))))))
erg))
)
@@ -2311,12 +2366,22 @@
(cons key (list 'OBJ (cons "formel" formel) (cons "quelle" quelle)))
)
;; Huelle einer bbox (ARR xmin ymin xmax ymax) als OBJ, nil ohne bbox.
(defun lg-huelle (bbox / b dx dy)
(if (setq b (cdr bbox))
(progn
(setq dx (- (caddr b) (car b)) dy (- (cadddr b) (cadr b)))
(list 'OBJ (cons "bbox" bbox) (cons "laenge_mm" (max dx dy)) (cons "breite_mm" (min dx dy)))))
)
;; Kennwerte eines Geschosses. g = Geschoss-Record, nx = Record des
;; naechsthoeheren Geschosses (nil = oberstes), reihen/gaenge = Records
;; dieses Geschosses (Reihen mit unter_reihe/gitterkorb), n-bereiche =
;; Anzahl Bereiche. Rueckgabe (kennwerte herkunft), beide OBJ.
;; Anzahl Bereiche. Rueckgabe (kennwerte herkunft), beide OBJ. Felder, die
;; nicht zutreffen (Belag/Gitterrost/Gitterkorb auf Hallenboden), sind
;; ENTFAELLT; nil = nicht berechenbar (fehlende Eingabe).
(defun lg-kennwerte-geschoss (g nx reihen gaenge n-bereiche / nrs q qr buehne hk lichte regal grund
schienen gitter-r korb gk l f belag-g gitter-g belag gitter)
rohr gitter-r offen-r korb gk l f u belag-g gitter-g belag gitter)
(setq nrs (vl-princ-to-string (lg-j g "nr"))
q (strcat "LG_GESCHOSS " nrs)
qr (strcat (itoa (length reihen)) " Regalreihe(n) LG_REIHE_* Geschoss " nrs)
@@ -2324,8 +2389,8 @@
hk nil)
;; lichte Hoehe: Vorgabe am Geschoss, sonst aus dem Geschoss darueber
(cond
((numberp (lg-j g "lichte_hoehe_mm"))
(setq lichte (lg-j g "lichte_hoehe_mm")
((numberp (lg-j g "lichte_hoehe_vorgabe_mm"))
(setq lichte (lg-j g "lichte_hoehe_vorgabe_mm")
hk (cons (lg-herkunft "lichte_hoehe_mm" "LICHTE_HOEHE_mm (Vorgabe am Geschoss)" q) hk)))
(nx
(setq lichte (- (lg-n (lg-j nx "hoehe_belag_mm")) (lg-n (lg-j nx "konstr_hoehe_mm"))
@@ -2334,31 +2399,37 @@
"HOEHE_BELAG_mm darueber - KONSTR_HOEHE_mm darueber - eigene HOEHE_BELAG_mm"
(strcat q " / " (vl-princ-to-string (lg-j nx "nr"))))
hk)))
(T (setq lichte nil))
(T (setq lichte nil
hk (cons (lg-herkunft "lichte_hoehe_mm"
"oberstes Geschoss ohne LICHTE_HOEHE_mm: nicht berechenbar (Eingabe fehlt)" q) hk)))
)
;; Regalreihen
(setq regal 0.0 grund 0.0 schienen 0.0 gitter-r 0.0 korb (list 0 0.0 0.0 0.0 0.0))
(setq regal 0.0 grund 0.0 rohr 0.0 gitter-r 0.0 offen-r 0.0 korb (list 0 0.0 0.0 0.0 0.0))
(foreach r reihen
(setq l (lg-n (lg-j r "laenge_mm"))
f (* l (lg-n (lg-j r "tiefe_mm"))))
f (* l (lg-n (lg-j r "tiefe_mm")))
u (lg-j r "unter_reihe"))
(setq regal (+ regal l) grund (+ grund f)
schienen (+ schienen (* l (if (numberp (lg-j r "schienen")) (lg-j r "schienen") 1))))
rohr (+ rohr (* l (length (cdr (lg-j r "haengeebenen"))))))
(cond
((equal (lg-j r "unter_reihe") "gitterrost") (setq gitter-r (+ gitter-r f)))
((equal u "gitterrost") (setq gitter-r (+ gitter-r f)))
((setq gk (lg-j r "gitterkorb"))
(setq korb (list (1+ (nth 0 korb))
(+ (nth 1 korb) (lg-n (lg-j gk "bodenflaeche_mm2")))
(+ (nth 2 korb) (lg-n (lg-j gk "seitenflaeche_mm2")))
(+ (nth 3 korb) (lg-n (lg-j gk "offen_laengs_mm")))
(+ (nth 4 korb) (lg-n (lg-j gk "offen_stirn_mm")))))))
(+ (nth 4 korb) (lg-n (lg-j gk "offen_stirn_mm"))))))
((equal u "keine") (setq offen-r (+ offen-r f))))
)
(setq hk (append (reverse
(list (lg-herkunft "regallaenge_mm" "Summe LAENGE der Regalreihen" qr)
(lg-herkunft "regalgrundflaeche_mm2" "Summe LAENGE x TIEFE_mm der Regalreihen" qr)
(lg-herkunft "schienenlaenge_mm" "Summe LAENGE x SCHIENEN der Regalreihen" qr)
(lg-herkunft "regalrohrlaenge_mm"
"Summe LAENGE x Anzahl Haengeebenen der Regalreihen (Regalrohr je Haengeebene; Trolley-Schienen nicht enthalten)" qr)
(lg-herkunft "haengeebenen" "je Schienenhoehe/Warenlaenge: Summe LAENGE aller Reihen mit dieser Haengeebene" qr)
(lg-herkunft "gaenge" "je ART: Anzahl, Summe LAENGE, Summe LAENGE x BREITE_mm"
(strcat (itoa (length gaenge)) " Flaeche(n) LG_GANG_* Geschoss " nrs))))
(lg-herkunft "gaenge" "je ART: Anzahl, Summe LAENGE, Summe LAENGE x BREITE_mm, Anzahl quer zur Reihenrichtung, Aufteilung nach BREITE_mm"
(strcat (itoa (length gaenge)) " Flaeche(n) LG_GANG_* Geschoss " nrs))
(lg-herkunft "huelle" "achsparallele Huelle der Belagskontur, laenge_mm = laengere Seite" q)))
hk))
;; Belag und Gitterrost (nur Buehne)
(setq belag-g 0.0 gitter-g 0.0)
@@ -2387,28 +2458,35 @@
(strcat "Reihen mit UNTER_REIHE gitterkorb: Boden = LAENGE x TIEFE_mm,"
" Seiten = offene Kantenlaenge x GITTERKORB_HOEHE_mm"
" (Kanten an einer direkt anliegenden Nachbarreihe zaehlen nicht)")
qr) hk))
(setq hk (cons (lg-herkunft "ohne_absturzsicherung_mm2"
"LAENGE x TIEFE_mm der Reihen mit UNTER_REIHE keine (offene Flaeche zum Geschoss darunter)"
qr) hk)))
(setq belag nil gitter nil
hk (cons (lg-herkunft "buehne" "BELAG_ART hallenboden (oder leer): keine Buehne, kein Belag/Gitterrost/Gitterkorb" q) hk))
(setq belag 'ENTFAELLT gitter 'ENTFAELLT
hk (cons (lg-herkunft "buehne" "BELAG_ART hallenboden (oder leer): keine Buehne - Belag, Gitterrost, Gitterkorb und Absturzsicherung entfallen" q) hk))
)
(list
(list 'OBJ
(cons "lichte_hoehe_mm" lichte)
(cons "buehne" (if buehne T 'FALSE))
(cons "huelle" (lg-huelle (lg-j (lg-j g "kontur") "bbox")))
(cons "bereiche" n-bereiche)
(cons "reihen" (length reihen))
(cons "regallaenge_mm" regal)
(cons "regalgrundflaeche_mm2" grund)
(cons "schienenlaenge_mm" schienen)
(cons "regalrohrlaenge_mm" rohr)
(cons "haengeebenen" (lg-haengeebenen-summen reihen))
(cons "gaenge" (lg-gaenge-je-art gaenge))
(cons "belagsflaeche_mm2" belag)
(cons "gitterrostflaeche_mm2" gitter)
(cons "gitterkorb" (list 'OBJ (cons "reihen" (nth 0 korb))
(cons "bodenflaeche_mm2" (nth 1 korb))
(cons "seitenflaeche_mm2" (nth 2 korb))
(cons "offen_laengs_mm" (nth 3 korb))
(cons "offen_stirn_mm" (nth 4 korb)))))
(cons "gitterkorb" (if buehne
(list 'OBJ (cons "reihen" (nth 0 korb))
(cons "bodenflaeche_mm2" (nth 1 korb))
(cons "seitenflaeche_mm2" (nth 2 korb))
(cons "offen_laengs_mm" (nth 3 korb))
(cons "offen_stirn_mm" (nth 4 korb)))
'ENTFAELLT))
(cons "ohne_absturzsicherung_mm2" (if buehne offen-r 'ENTFAELLT)))
(cons 'OBJ (reverse hk)))
)
@@ -2416,36 +2494,134 @@
(apply '+ (cons 0.0 (mapcar '(lambda (o) (lg-n (lg-j o key))) objs)))
)
;; Kennwerte des ganzen Lagers. geschosse = Geschoss-Records mit kennwerte
;; und kontur, reihen/gaenge = alle einem Geschoss zugeordneten Records.
(defun lg-kennwerte-lager (geschosse reihen gaenge n-bereiche / kws korb bbs xmin ymin xmax ymax dx dy)
;; Kennwerte des ganzen Lagers. geschosse = Geschoss-Records mit kennwerte,
;; reihen/gaenge = alle einem Geschoss zugeordneten Records. Die Summen
;; stehen ausdruecklich unter summe_alle_geschosse; grundriss_max ist der
;; groesste Geschossgrundriss (die Geschosse koennen im Plan nebeneinander
;; liegen - eine gemeinsame Huelle waere kein Gebaeudemass).
(defun lg-kennwerte-lager (geschosse reihen gaenge n-bereiche / kws korb hs)
(setq kws (mapcar '(lambda (g) (lg-j g "kennwerte")) geschosse)
korb (mapcar '(lambda (k) (lg-j k "gitterkorb")) kws)
bbs (vl-remove nil (mapcar '(lambda (g) (cdr (lg-j (lg-j g "kontur") "bbox"))) geschosse)))
(if bbs
(setq xmin (apply 'min (mapcar 'car bbs)) ymin (apply 'min (mapcar 'cadr bbs))
xmax (apply 'max (mapcar 'caddr bbs)) ymax (apply 'max (mapcar 'cadddr bbs))
dx (- xmax xmin) dy (- ymax ymin)))
korb (vl-remove nil (mapcar '(lambda (k) (lg-j k "gitterkorb")) kws))
hs (vl-remove nil (mapcar '(lambda (k) (lg-j k "huelle")) kws)))
(list 'OBJ
(cons "geschosse" (length geschosse))
(cons "bereiche" n-bereiche)
(cons "reihen" (length reihen))
(cons "regallaenge_mm" (lg-summe-feld kws "regallaenge_mm"))
(cons "regalgrundflaeche_mm2" (lg-summe-feld kws "regalgrundflaeche_mm2"))
(cons "schienenlaenge_mm" (lg-summe-feld kws "schienenlaenge_mm"))
(cons "haengeebenen" (lg-haengeebenen-summen reihen))
(cons "gaenge" (lg-gaenge-je-art gaenge))
(cons "belagsflaeche_mm2" (lg-summe-feld kws "belagsflaeche_mm2"))
(cons "gitterrostflaeche_mm2" (lg-summe-feld kws "gitterrostflaeche_mm2"))
(cons "gitterkorb" (list 'OBJ (cons "reihen" (fix (lg-summe-feld korb "reihen")))
(cons "bodenflaeche_mm2" (lg-summe-feld korb "bodenflaeche_mm2"))
(cons "seitenflaeche_mm2" (lg-summe-feld korb "seitenflaeche_mm2"))
(cons "offen_laengs_mm" (lg-summe-feld korb "offen_laengs_mm"))
(cons "offen_stirn_mm" (lg-summe-feld korb "offen_stirn_mm"))))
(cons "huelle" (if bbs
(list 'OBJ (cons "bbox" (list 'ARR xmin ymin xmax ymax))
(cons "laenge_mm" (max dx dy))
(cons "breite_mm" (min dx dy))))))
(cons "grundriss_max" (if hs
(list 'OBJ (cons "laenge_mm" (apply 'max (mapcar '(lambda (h) (lg-j h "laenge_mm")) hs)))
(cons "breite_mm" (apply 'max (mapcar '(lambda (h) (lg-j h "breite_mm")) hs))))))
(cons "summe_alle_geschosse"
(list 'OBJ
(cons "reihen" (length reihen))
(cons "regallaenge_mm" (lg-summe-feld kws "regallaenge_mm"))
(cons "regalgrundflaeche_mm2" (lg-summe-feld kws "regalgrundflaeche_mm2"))
(cons "regalrohrlaenge_mm" (lg-summe-feld kws "regalrohrlaenge_mm"))
(cons "haengeebenen" (lg-haengeebenen-summen reihen))
(cons "gaenge" (lg-gaenge-je-art gaenge))
(cons "belagsflaeche_mm2" (lg-summe-feld kws "belagsflaeche_mm2"))
(cons "gitterrostflaeche_mm2" (lg-summe-feld kws "gitterrostflaeche_mm2"))
(cons "gitterkorb" (list 'OBJ (cons "reihen" (fix (lg-summe-feld korb "reihen")))
(cons "bodenflaeche_mm2" (lg-summe-feld korb "bodenflaeche_mm2"))
(cons "seitenflaeche_mm2" (lg-summe-feld korb "seitenflaeche_mm2"))
(cons "offen_laengs_mm" (lg-summe-feld korb "offen_laengs_mm"))
(cons "offen_stirn_mm" (lg-summe-feld korb "offen_stirn_mm"))))
(cons "ohne_absturzsicherung_mm2" (lg-summe-feld kws "ohne_absturzsicherung_mm2")))))
)
;; --- Plausibilitaet (reiner Kern, getestet) ---
;; Prueft ein Geschoss auf Eingaben, die fuer die Ausschreibung kaum stimmen
;; koennen. grenzen = Alist aus dem Regelwerk (("gang_min" wert quelle)
;; ("lichte_min" wert quelle)), fehlende Grenzen werden nicht geprueft.
;; Rueckgabe: Liste von Warntexten.
(defun lg-plausibilitaet (g kw reihen gaenge grenzen / nrs w buehne gm lm schmal quer rand neben
ebenen-texte frei top lichte)
(setq nrs (vl-princ-to-string (lg-j g "nr")) w nil
buehne (lg-buehne-p (lg-j g "belag_art"))
lichte (lg-j kw "lichte_hoehe_mm")
gm (cdr (assoc "gang_min" grenzen))
lm (cdr (assoc "lichte_min" grenzen)))
;; Buehne ohne Konstruktionshoehe
(if (and buehne (<= (lg-n (lg-j g "konstr_hoehe_mm")) 0.0))
(setq w (cons (ssg-textf "lg-pl-konstr-null" (list nrs)) w)))
;; Buehne mit offenen Flaechen unter Reihen
(if (and buehne (> (lg-n (lg-j kw "ohne_absturzsicherung_mm2")) 0.0))
(setq w (cons (ssg-textf "lg-pl-unter-keine"
(list nrs (rtos (/ (lg-j kw "ohne_absturzsicherung_mm2") 1.0e6) 2 1))) w)))
;; lichte Hoehe unter dem Regelwerk
(if (and lm (numberp lichte) (< lichte (car lm)))
(setq w (cons (ssg-textf "lg-pl-lichte-klein"
(list nrs (lg-mm-str lichte) (lg-mm-str (car lm)) (cadr lm))) w)))
;; zu schmale Gaenge
(if gm
(progn
(setq schmal (vl-remove-if-not '(lambda (x) (< (lg-n (lg-j x "breite_mm")) (car gm))) gaenge))
(if schmal
(setq w (cons (ssg-textf "lg-pl-gang-schmal"
(list nrs (itoa (length schmal))
(ssg-join (lg-unikat (mapcar '(lambda (x) (lg-mm-str (lg-j x "breite_mm"))) schmal)) ", ")
(lg-mm-str (car gm)) (cadr gm))) w)))))
;; als "gang" eingetragen, liegt aber quer zur Reihenrichtung
(setq quer (vl-remove-if-not '(lambda (x) (and (equal (lg-j x "art") "gang")
(equal (lg-j x "ausrichtung") "quer")))
gaenge))
(if quer
(setq w (cons (ssg-textf "lg-pl-gang-quer"
(list nrs (itoa (length quer)) (ssg-join (mapcar '(lambda (x) (vl-princ-to-string (lg-j x "id"))) quer) ", ")))
w)))
;; Gang direkt neben einem Randgang (doppelte Randzone?)
(setq rand (mapcar '(lambda (x) (mapcar 'cdr (cdr (lg-j x "ecken"))))
(vl-remove-if-not '(lambda (x) (equal (lg-j x "art") "randgang")) gaenge)))
(if rand
(progn
(setq neben (vl-remove-if-not
'(lambda (x / e k)
(if (not (equal (lg-j x "art") "randgang"))
(progn
(setq e (mapcar 'cdr (cdr (lg-j x "ecken"))) k (lg-rechteck-kanten e))
(vl-some '(lambda (kante / len)
(setq len (distance (car kante) (cadr kante)))
(< (lg-kante-offen kante rand 1.0) (- len 1.0)))
(list (nth 0 k) (nth 2 k))))))
gaenge))
(if neben
(setq w (cons (ssg-textf "lg-pl-gang-neben-randgang"
(list nrs (itoa (length neben)) (ssg-join (mapcar '(lambda (x) (vl-princ-to-string (lg-j x "id"))) neben) ", ")))
w)))))
;; Haengeebenen: kein Freiraum unter der Ware, oberste Schiene ueber der lichten Hoehe
(setq ebenen-texte nil top nil)
(foreach r reihen
(foreach e (cdr (lg-j r "haengeebenen"))
(if (or (null top) (> (lg-n (lg-j e "schienenhoehe_mm")) top)) (setq top (lg-n (lg-j e "schienenhoehe_mm"))))
(if (<= (lg-n (lg-j e "freiraum_unter_mm")) 0.0)
(setq ebenen-texte (cons (strcat (lg-mm-str (lg-j e "schienenhoehe_mm")) "/" (lg-mm-str (lg-j e "warenlaenge_mm"))
" (" (lg-mm-str (lg-j e "freiraum_unter_mm")) ")")
ebenen-texte)))))
(if ebenen-texte
(setq w (cons (ssg-textf "lg-pl-freiraum" (list nrs (ssg-join (lg-unikat (reverse ebenen-texte)) ", "))) w)))
(if (and top (numberp lichte) (>= top lichte))
(setq w (cons (ssg-textf "lg-pl-schiene-ueber-lichte" (list nrs (lg-mm-str top) (lg-mm-str lichte))) w)))
(reverse w)
)
;; Liste ohne Wiederholungen, Reihenfolge des ersten Auftretens.
(defun lg-unikat (l / erg)
(foreach x l (if (not (member x erg)) (setq erg (cons x erg))))
(reverse erg)
)
;; Grenzwerte fuer lg-plausibilitaet aus dem Regelprofil des Landes, mit
;; dem Geschoss als Kontext. Fehlt das Profil, bleibt die Liste leer.
(defun lg-plausibilitaet-grenzen (g land / kontext regel erg w)
(setq kontext (vl-remove-if '(lambda (p) (null (cdr p)))
(list (cons "brandgefaehrdung" (lg-j g "brandgefaehrdung"))
(cons "personen" (lg-j g "personen"))))
erg nil)
(foreach p '(("gang_min" . "gang.breite_nebengang_min") ("lichte_min" . "lichte_hoehe.verkehrsweg_min"))
(if (and (car (atoms-family 1 '("LG-REGEL-AUFLOESEN")))
(setq regel (lg-regel-finden (lg-profil land) (cdr p)))
(setq w (lg-regel-aufloesen regel kontext))
(numberp (car w)))
(setq erg (cons (list (car p) (float (car w)) (strcat (cdr p) ": " (lg-eintrag-quelle (cadr w)))) erg))))
erg
)
;; --- Records aus der Zeichnung ---
@@ -2473,7 +2649,8 @@
(cons "layer" (lg-ent-layer (car g)))
(cons "hoehe_belag_mm" (lg-a-zahl a "HOEHE_BELAG_mm"))
(cons "konstr_hoehe_mm" (lg-a-zahl a "KONSTR_HOEHE_mm"))
(cons "lichte_hoehe_mm" (lg-a-zahl a "LICHTE_HOEHE_mm"))
;; nur die Eingabe am Geschoss; der wirksame Wert steht in kennwerte
(cons "lichte_hoehe_vorgabe_mm" (cond ((lg-a-zahl a "LICHTE_HOEHE_mm")) ('ENTFAELLT)))
(cons "belag_art" (cdr (assoc "BELAG_ART" a)))
(cons "personen" (lg-a-int a "PERSONEN"))
(cons "brandgefaehrdung" (cdr (assoc "BRANDGEFAEHRDUNG" a)))
@@ -2490,7 +2667,8 @@
(cons "gangbreite_mm" (lg-a-zahl a "GANGBREITE_mm"))
(cons "regaltiefe_mm" (lg-a-zahl a "REGALTIEFE_mm"))
(cons "reihen_je_gang" (lg-a-int a "REIHEN_JE_GANG"))
(cons "schienen_je_gang" (lg-a-int a "SCHIENEN_JE_GANG"))
;; Trolley-Schienen je Gang: Eingabe, wird noch nicht ausgewertet
(cons "trolleyschienen_je_gang" (lg-a-int a "SCHIENEN_JE_GANG"))
(cons "quergang_abstand_mm" (lg-a-zahl a "QUERGANG_ABSTAND_mm"))
(cons "quergang_breite_mm" (lg-a-zahl a "QUERGANG_BREITE_mm"))
(cons "richtung_grad" (lg-a-zahl a "RICHTUNG"))
@@ -2508,8 +2686,8 @@
;; Reihe oder Gang: Attribute plus Geometrie (Start/Ende/Mitte in WCS mit Z,
;; Ecken des Grundrisses 2D aus lg-linie-polygon).
(defun lg-export-linie-rec (e art / a ed p1 z rot l b p2 quelle)
(setq a (ssg-attrib-read e) ed (entget e)
(defun lg-export-linie-rec (e art / a ed p1 z rot l b p2 quelle bh)
(setq a (ssg-attrib-read e) ed (entget e) bh (lg-xdata-wert e "bereich")
p1 (cdr (assoc 10 ed)) z (cond ((caddr p1)) (0.0))
rot (cond ((cdr (assoc 50 ed))) (0.0))
l (lg-a-zahl a "LAENGE")
@@ -2523,13 +2701,13 @@
(cons "handle" (lg-handle e))
(cons "layer" (lg-ent-layer e))
(cons "geschoss" (lg-a-int a "GESCHOSS"))
(cons "bereich" (lg-a-int a "BEREICH"))
(cons "bereich_handle" (lg-xdata-wert e "bereich"))
;; ohne Bereich (frei gesetzt) entfallen beide Felder
(cons "bereich" (if bh (lg-a-int a "BEREICH") 'ENTFAELLT))
(cons "bereich_handle" (if bh bh 'ENTFAELLT))
(cons "quelle" quelle)
(cons "laenge_mm" l))
(if (= art "reihe")
(list (cons "tiefe_mm" b)
(cons "schienen" (lg-a-int a "SCHIENEN"))
(cons "haengeebenen" (lg-j-ebenen (cdr (assoc "HAENGEEBENEN" a)))))
(list (cons "breite_mm" b)
(cons "art" (cdr (assoc "ART" a)))
@@ -2556,12 +2734,25 @@
"gitterkorb"
(if (= u "gitterkorb")
(list 'OBJ (cons "hoehe_mm" (cond ((lg-j br "gitterkorb_hoehe_mm"))
((lg-zahl (lg-vorgabe '("bereich" "gitterkorb_hoehe_mm") nil)))))))))
((lg-zahl (lg-vorgabe '("bereich" "gitterkorb_hoehe_mm") nil))))))
'ENTFAELLT)))
reihen)
)
;; ausrichtung je Gang (laengs/quer) gegen die Reihenrichtung seines Bereichs;
;; ohne Bereich entfaellt das Feld.
(defun lg-gaenge-ausrichtung-setzen (gaenge bereiche / br)
(mapcar
'(lambda (x / br)
(setq br (if (lg-j x "bereich_handle")
(vl-some '(lambda (b) (if (equal (lg-j b "handle") (lg-j x "bereich_handle")) b)) bereiche)))
(lg-j-setzen x "ausrichtung"
(cond ((lg-ausrichtung (lg-j x "winkel_grad") (lg-j br "richtung_grad"))) ('ENTFAELLT))))
gaenge)
)
;; Alle Daten des Lagers als OBJ (Grundlage von lg-export-json).
(defun lg-export-daten ( / warn gs bereiche reihen gaenge g-recs vorgabe g-neu r-neu r-gs g-gs i g nx nr nrs kw)
(defun lg-export-daten ( / warn gs bereiche reihen gaenge g-recs vorgabe g-neu r-neu r-gs g-gs i g nx nr nrs kw t1)
(setq gs (lg-geschosse) warn nil vorgabe (lg-unter-reihe-vorgabe))
(if (null gs) (setq warn (cons (ssg-text "lg-exp-keine-geschosse") warn)))
(foreach g gs
@@ -2575,7 +2766,8 @@
'(lambda (a b / ha hb)
(setq ha (lg-n (lg-j a "hoehe_belag_mm")) hb (lg-n (lg-j b "hoehe_belag_mm")))
(if (equal ha hb 1e-6) (< (lg-j a "nr") (lg-j b "nr")) (< ha hb)))))
(setq reihen (lg-reihen-unter-setzen reihen bereiche g-recs vorgabe))
(setq reihen (lg-reihen-unter-setzen reihen bereiche g-recs vorgabe)
gaenge (lg-gaenge-ausrichtung-setzen gaenge bereiche))
(setq g-neu nil r-neu nil r-gs nil g-gs nil i 0)
(foreach g g-recs
(setq nr (lg-j g "nr")
@@ -2592,6 +2784,9 @@
(if (and (equal (lg-j b "geschoss") nr) (= (lg-j b "unter_reihe") "gitterkorb"))
(setq warn (cons (ssg-textf "lg-exp-korb-hallenboden"
(list (vl-princ-to-string (lg-j b "nr")) (itoa nr))) warn)))))
;; Plausibilitaet gegen das Regelprofil (nur Warnungen)
(foreach t1 (lg-plausibilitaet g (car kw) r-gs g-gs (lg-plausibilitaet-grenzen g (lg-land)))
(setq warn (cons t1 warn)))
(setq g-neu (cons (lg-j-setzen (lg-j-setzen g "kennwerte" (car kw)) "herkunft" (cadr kw)) g-neu)
r-neu (append r-neu r-gs)
i (1+ i)))
+2 -3
View File
@@ -41,8 +41,7 @@
},
"reihe": {
"beschreibung": "haengeebenen = Schienenhoehe ueber Belag / max. Warenlaenge je Haengeebene, durch Semikolon getrennt, oberste zuerst.",
"haengeebenen": "2300/1200;1100/1100",
"schienen": 1
"beschreibung": "haengeebenen = Schienenhoehe ueber Belag / max. Warenlaenge je Haengeebene, durch Semikolon getrennt, oberste zuerst. Jede Haengeebene ist ein Regalrohr ueber die Reihenlaenge.",
"haengeebenen": "2300/1200;1100/1100"
}
}
+1 -2
View File
@@ -41,7 +41,7 @@ lg_bereich : dialog {
: edit_box { key = "gang"; label = "Gangbreite:"; edit_width = 10; }
: edit_box { key = "tiefe"; label = "Regaltiefe:"; edit_width = 10; }
: popup_list { key = "reihen"; label = "Reihen je Gang:"; width = 20; }
: edit_box { key = "schienen"; label = "Schienen je Gang:"; edit_width = 10; }
: edit_box { key = "schienen"; label = "Trolley-Schienen je Gang:"; edit_width = 10; }
: edit_box { key = "richtung"; label = "Reihenrichtung (Grad):"; edit_width = 10; }
}
: boxed_column {
@@ -114,7 +114,6 @@ lg_reihe : dialog {
: edit_box { key = "laenge"; label = "Laenge (mm):"; edit_width = 10; }
: edit_box { key = "tiefe"; label = "Regaltiefe (mm):"; edit_width = 10; }
: edit_box { key = "ebenen"; label = "Haengeebenen (Schiene/Ware;...):"; edit_width = 24; }
: edit_box { key = "schienen"; label = "Schienen:"; edit_width = 10; }
}
ok_cancel;
errtile;
+48 -22
View File
@@ -26,32 +26,41 @@ Overlay-YAML `lib/lager_yaml_export.py` und `LAGER_HAND_YAML` sind entfernt).
## JSON-Schnittstelle (`format` = `ssg-lager`, `version` = 2)
Einheiten mm, mm2, Grad; Koordinaten WCS, Nord = +Y. Werte stehen
selbstbeschreibend drin (`"belag_art": "spanplatte"`, keine Index-Codes). Fehlende
Werte sind `null`. Nicht-ASCII-Zeichen in Texten werden als `\uXXXX` geschrieben.
selbstbeschreibend drin (`"belag_art": "spanplatte"`, keine Index-Codes).
Nicht-ASCII-Zeichen in Texten werden als `\uXXXX` geschrieben.
**Regel fuer fehlende Werte:** `null` heisst ausschliesslich "fehlt, muesste
eingegeben werden" (offener Punkt, z.B. `kennwerte.lichte_hoehe_mm` des obersten
Geschosses ohne Vorgabe). Was nicht zutrifft, wird WEGGELASSEN: Belag,
Gitterrost, Gitterkorb und `ohne_absturzsicherung_mm2` auf Hallenboden,
`gitterkorb` an Reihen ohne Korb, `bereich`/`bereich_handle`/`ausrichtung` an frei
gesetzten Reihen und Gaengen, `lichte_hoehe_vorgabe_mm` ohne Vorgabe.
```
{
"format": "ssg-lager", "version": 2, "zeichnung", "erzeugt", "land",
"einheiten": {"laenge": "mm", "flaeche": "mm2", "winkel": "grad"},
"koordinaten": "WCS, Nord = +Y",
"lager": { geschosse, bereiche, reihen, regallaenge_mm, regalgrundflaeche_mm2,
schienenlaenge_mm, haengeebenen[], gaenge{}, belagsflaeche_mm2,
gitterrostflaeche_mm2, gitterkorb{}, huelle{bbox, laenge_mm, breite_mm} },
"lager": { geschosse, bereiche, grundriss_max{laenge_mm, breite_mm},
summe_alle_geschosse{reihen, regallaenge_mm, regalgrundflaeche_mm2,
regalrohrlaenge_mm, haengeebenen[], gaenge{}, belagsflaeche_mm2,
gitterrostflaeche_mm2, gitterkorb{}, ohne_absturzsicherung_mm2} },
"geschosse": [ { nr, bezeichnung, id, handle, layer, hoehe_belag_mm, konstr_hoehe_mm,
lichte_hoehe_mm (Attribut), belag_art, personen, brandgefaehrdung,
lichte_hoehe_vorgabe_mm (nur wenn eingegeben), belag_art, personen, brandgefaehrdung,
kontur{handle, z, punkte[[x,y]...], flaeche_mm2, umfang_mm, bbox},
kennwerte{...}, herkunft{<kennwert>: {formel, quelle}} } ],
"bereiche": [ { nr, id, handle, layer, geschoss, gangbreite_mm, regaltiefe_mm,
reihen_je_gang, schienen_je_gang, quergang_abstand_mm, quergang_breite_mm,
reihen_je_gang, trolleyschienen_je_gang, quergang_abstand_mm, quergang_breite_mm,
richtung_grad, haengeebenen[], belag, unter_reihe, gitterkorb_hoehe_mm,
randgang_mm{n,o,s,w}, restbreite_mm, anzahl_reihen, anzahl_gaenge, kontur{} } ],
"reihen": [ { id, handle, layer, geschoss, bereich, bereich_handle, quelle, laenge_mm,
tiefe_mm, schienen, haengeebenen[], start, ende, mitte, winkel_grad,
ecken[4], flaeche_mm2, unter_reihe,
tiefe_mm, haengeebenen[{schienenhoehe_mm, warenlaenge_mm, freiraum_unter_mm}],
start, ende, mitte, winkel_grad, ecken[4], flaeche_mm2, unter_reihe,
gitterkorb{hoehe_mm, bodenflaeche_mm2, offen_laengs_mm, offen_stirn_mm,
seitenflaeche_mm2} | null } ],
seitenflaeche_mm2} (nur bei Gitterkorb) } ],
"gaenge": [ { id, handle, layer, geschoss, bereich, bereich_handle, quelle, laenge_mm,
breite_mm, art, belag, start, ende, mitte, winkel_grad, ecken[4], flaeche_mm2 } ],
breite_mm, art, belag, start, ende, mitte, winkel_grad, ecken[4], flaeche_mm2,
ausrichtung ("laengs"/"quer" zur Reihenrichtung des Bereichs) } ],
"warnungen": [ ... ]
}
```
@@ -59,12 +68,25 @@ Werte sind `null`. Nicht-ASCII-Zeichen in Texten werden als `\uXXXX` geschrieben
`geschosse` ist nach Belagshoehe sortiert (von unten nach oben). `start`/`ende`/
`mitte` sind 3D (Z der Einfuegung), `ecken` sind die vier Ecken des Grundrisses
(2D), Kante 1-2 und 3-4 laengs, 2-3 und 4-1 an den Stirnseiten.
`kennwerte` je Geschoss: `lichte_hoehe_mm`, `buehne` (true/false), `bereiche`,
`reihen`, `regallaenge_mm`, `regalgrundflaeche_mm2`, `schienenlaenge_mm`,
`haengeebenen` (je Schienenhoehe/Warenlaenge: `reihen`, `regallaenge_mm`),
`gaenge` (je Art gang/quergang/randgang: `anzahl`, `laenge_mm`, `flaeche_mm2`),
`belagsflaeche_mm2`, `gitterrostflaeche_mm2`, `gitterkorb` (Summen). Formeln:
Abschnitt "Kennwerte <- Zeichnung".
`kennwerte` je Geschoss: `lichte_hoehe_mm` (wirksamer Wert: Vorgabe oder
berechnet), `buehne` (true/false), `huelle` (Grundriss dieses Geschosses),
`bereiche`, `reihen`, `regallaenge_mm`, `regalgrundflaeche_mm2`,
`regalrohrlaenge_mm`, `haengeebenen` (je Schienenhoehe/Warenlaenge: `reihen`,
`regallaenge_mm`), `gaenge` (je Art gang/quergang/randgang: `anzahl`,
`laenge_mm`, `flaeche_mm2`, `anzahl_quer`, `nach_breite[]`),
`belagsflaeche_mm2`, `gitterrostflaeche_mm2`, `gitterkorb` (Summen),
`ohne_absturzsicherung_mm2`. Formeln: Abschnitt "Kennwerte <- Zeichnung".
Alles unter `lager.summe_alle_geschosse` ist ueber ALLE Geschosse summiert.
Trolley-Schienen werden noch nicht berechnet (`trolleyschienen_je_gang` ist nur
die Eingabe am Bereich).
`warnungen` enthaelt neben fehlenden Daten Plausibilitaetshinweise je Geschoss
(`lg-plausibilitaet`; Grenzwerte aus dem Regelprofil, `lg-plausibilitaet-grenzen`):
Buehne ohne Konstruktionshoehe, Reihen ohne Absturzsicherung auf einer Buehne,
lichte Hoehe unter `lichte_hoehe.verkehrsweg_min`, Gaenge schmaler als
`gang.breite_nebengang_min`, `art` gang quer zur Reihenrichtung, Gang direkt
neben einem Randgang, kein Freiraum unter der Ware, oberste Schiene nicht unter
der lichten Hoehe. Sie aendern keine Werte.
Erzeugt von `LAGER_EXPORT` (Menue Lager -> Export Lager-JSON), Beispiel:
`tests/output/lager_tests_lager.json` nach `TEST_LAGER`.
@@ -78,8 +100,8 @@ Werte selbstbeschreibend (keine Index-Codes). Verknuepfungen als XDATA
| Block | Geometrie | Attribute | XDATA |
|---|---|---|---|
| `LG_GESCHOSS` | Kopfsymbol unten links an der Belagskontur | `NR`, `BEZEICHNUNG`, `HOEHE_BELAG_mm`, `KONSTR_HOEHE_mm`, `LICHTE_HOEHE_mm` (leer = berechnet), `BELAG_ART` (`spanplatte`/`gitterrost`/`hallenboden`), `PERSONEN`, `BRANDGEFAEHRDUNG` | `kontur` -> Polylinie; Kontur: `besitzer`, `rolle` |
| `LG_BEREICH` | Symbol mit Pfeil in Reihenrichtung | `NR`, `GANGBREITE_mm`, `REGALTIEFE_mm`, `REIHEN_JE_GANG` (1/2), `SCHIENEN_JE_GANG`, `QUERGANG_ABSTAND_mm` (0 = keine), `QUERGANG_BREITE_mm`, `RICHTUNG`, `HAENGEEBENEN`, `BELAG`, `RANDGANG_N_mm`/`_O_`/`_S_`/`_W_` (0 = keiner), `UNTER_REIHE` (`gitterrost`/`gitterkorb`/`keine`, Absturzsicherung unter den Reihen, nur auf Buehnen), `GITTERKORB_HOEHE_mm`, `RESTBREITE_mm` (Ergebnis) | `kontur` -> Polylinie |
| `LG_REIHE_<L>_<T>` | Rechteck L x T um die Schienenlinie, Einfuegepunkt = Reihenanfang | `LAENGE`, `TIEFE_mm`, `HAENGEEBENEN`, `SCHIENEN`, `BEREICH`, `QUELLE` (`auto`/`auto_geaendert`/`manuell`) | `bereich` -> LG_BEREICH (nur Auto-Fuellung) |
| `LG_BEREICH` | Symbol mit Pfeil in Reihenrichtung | `NR`, `GANGBREITE_mm`, `REGALTIEFE_mm`, `REIHEN_JE_GANG` (1/2), `SCHIENEN_JE_GANG` (Trolley-Schienen, noch nicht ausgewertet), `QUERGANG_ABSTAND_mm` (0 = keine), `QUERGANG_BREITE_mm`, `RICHTUNG`, `HAENGEEBENEN`, `BELAG`, `RANDGANG_N_mm`/`_O_`/`_S_`/`_W_` (0 = keiner), `UNTER_REIHE` (`gitterrost`/`gitterkorb`/`keine`, Absturzsicherung unter den Reihen, nur auf Buehnen), `GITTERKORB_HOEHE_mm`, `RESTBREITE_mm` (Ergebnis) | `kontur` -> Polylinie |
| `LG_REIHE_<L>_<T>` | Rechteck L x T um die Schienenlinie, Einfuegepunkt = Reihenanfang | `LAENGE`, `TIEFE_mm`, `HAENGEEBENEN` (je Ebene ein Regalrohr), `BEREICH`, `QUELLE` (`auto`/`auto_geaendert`/`manuell`) | `bereich` -> LG_BEREICH (nur Auto-Fuellung) |
| `LG_GANG_<L>_<B>_<BELAG>` | Rechteck L x B um die Gangachse + Schraffur je Belag (`lager.json belag_schraffur`, Layer 0/VONBLOCK; `hallenboden` ohne) | `LAENGE`, `BREITE_mm`, `ART` (`gang`/`quergang`/`randgang`), `BELAG`, `BEREICH`, `QUELLE` (`auto`/`auto_geaendert`/`manuell`) | `bereich` (Auto-Fuellung und manuelle Gaenge im Bereich) |
`HAENGEEBENEN` = `Schienenhoehe/Warenlaenge;...` ueber Belag, oberste zuerst,
@@ -208,14 +230,18 @@ Geschoss-Kennwert steht mit Formel und Quelle unter `herkunft`.
|---|---|
| `lichte_hoehe_mm` | `LICHTE_HOEHE_mm`, sonst Belag darueber - Konstruktionshoehe darueber - eigener Belag; oberstes Geschoss nur mit Vorgabe (sonst `null` + Warnung) |
| `buehne` | `BELAG_ART` gesetzt und nicht `hallenboden`. Ohne Buehne: kein Belag, kein Gitterrost, kein Gitterkorb |
| `regallaenge_mm`, `regalgrundflaeche_mm2`, `schienenlaenge_mm` | Summe `LAENGE`, `LAENGE x TIEFE_mm`, `LAENGE x SCHIENEN` der Reihen des Geschosses |
| `regallaenge_mm`, `regalgrundflaeche_mm2`, `regalrohrlaenge_mm` | Summe `LAENGE`, `LAENGE x TIEFE_mm`, `LAENGE x Anzahl Haengeebenen` der Reihen des Geschosses |
| `ohne_absturzsicherung_mm2` | Buehne: Summe `LAENGE x TIEFE_mm` der Reihen mit `UNTER_REIHE = keine` |
| `haengeebenen[].freiraum_unter_mm` (Reihe/Bereich) | Schienenhoehe - Warenlaenge - naechsttiefere Schienenhoehe (unterste: Belag); <= 0 = Ware stoesst an (`lg-ebenen-freiraum`) |
| `gaenge[].ausrichtung` | Gangwinkel gegen `RICHTUNG` des Bereichs, Abweichung < 45 Grad = laengs (`lg-ausrichtung`) |
| `haengeebenen[]` | je (Schienenhoehe, Warenlaenge): Anzahl Reihen und Summe `LAENGE`, nach Schienenhoehe absteigend (`lg-haengeebenen-summen`) |
| `gaenge` | je `ART` (gang/quergang/randgang, auch manuelle): Anzahl, Summe `LAENGE`, Summe `LAENGE x BREITE_mm` (`lg-gaenge-je-art`) |
| `belagsflaeche_mm2` | Summe `LAENGE x BREITE_mm` der Gaenge mit Belag != gitterrost; ohne Gangflaechen: Konturflaeche - Reihengrundflaeche |
| `gitterrostflaeche_mm2` | Gaenge mit Belag gitterrost + Grundflaeche der Reihen mit `UNTER_REIHE = gitterrost` |
| `gitterkorb` (je Reihe und Summe) | Reihen mit `UNTER_REIHE = gitterkorb`: Boden = `LAENGE x TIEFE_mm`; Seiten = offene Kantenlaenge x `GITTERKORB_HOEHE_mm`, getrennt nach Laengs- und Stirnseiten. Offen ist eine Kante, soweit keine Kante einer ANDEREN Reihe desselben Geschosses kollinear darauf liegt (Abstand < 1 mm, z.B. Ruecken an Ruecken; `lg-reihen-offene-kanten`) |
| `lager.huelle` | achsparallele Huelle aller Geschosskonturen, `laenge_mm` = laengere Seite |
| `lager.*` sonst | Summen der Geschoss-Kennwerte; `haengeebenen`/`gaenge` ueber alle zugeordneten Reihen/Gaenge |
| `kennwerte.huelle` | achsparallele Huelle der Geschosskontur, `laenge_mm` = laengere Seite |
| `lager.grundriss_max` | groesste Laenge/Breite der Geschoss-Huellen (die Geschosse koennen im Plan nebeneinander liegen - eine gemeinsame Huelle waere kein Gebaeudemass) |
| `lager.summe_alle_geschosse` | Summen der Geschoss-Kennwerte; `haengeebenen`/`gaenge` ueber alle zugeordneten Reihen/Gaenge |
`UNTER_REIHE` kommt aus dem verknuepften Bereich; Reihen ohne Bereich (und
Bereiche ohne Attribut, Altbestand) nehmen die Vorgabe `lager.json
+9 -1
View File
@@ -1203,7 +1203,6 @@
"lg-feld-gang": "\nGangbreite (mm)",
"lg-feld-tiefe": "\nRegaltiefe (mm)",
"lg-feld-reihen": "\nReihen je Gang",
"lg-feld-schienen": "\nSchienen je Gang",
"lg-feld-q_abstand": "\nQuergang-Abstand (mm, 0 = keine)",
"lg-feld-q_breite": "\nQuergang-Breite (mm)",
"lg-feld-richtung": "\nReihenrichtung (Grad)",
@@ -1275,6 +1274,15 @@
"lg-exp-lichte-hoehe-oben": "Geschoss %1 (oberstes): lichte Hoehe nicht berechenbar - LICHTE_HOEHE_mm setzen.",
"lg-exp-korb-hallenboden": "Bereich %1 hat Gitterkorb unter den Reihen, Geschoss %2 ist aber Hallenboden - nicht gezaehlt.",
"lg-exp-reihen-ohne-geschoss": "%1 Regalreihe(n) ohne bekanntes Geschoss - nicht in den Kennwerten enthalten.",
"lg-feld-schienen": "\nTrolley-Schienen je Gang",
"lg-pl-konstr-null": "Geschoss %1 ist eine Buehne, hat aber keine Konstruktionshoehe (KONSTR_HOEHE_mm = 0).",
"lg-pl-unter-keine": "Geschoss %1: %2 m2 Regalgrundflaeche ohne Absturzsicherung (UNTER_REIHE keine) - offene Flaeche zum Geschoss darunter.",
"lg-pl-lichte-klein": "Geschoss %1: lichte Hoehe %2 mm unter dem Mindestmass %3 mm (%4).",
"lg-pl-gang-schmal": "Geschoss %1: %2 Gang/Gaenge schmaler als %4 mm (Breiten %3 mm; %5).",
"lg-pl-gang-quer": "Geschoss %1: %2 Gang/Gaenge mit ART gang liegen quer zur Reihenrichtung (ID %3) - Quergang?",
"lg-pl-gang-neben-randgang": "Geschoss %1: %2 Gang/Gaenge liegen direkt neben einem Randgang (ID %3) - doppelte Randzone?",
"lg-pl-freiraum": "Geschoss %1: kein Freiraum unter der Ware bei Haengeebene(n) Schiene/Ware (Freiraum) %2 mm.",
"lg-pl-schiene-ueber-lichte": "Geschoss %1: oberste Schiene %2 mm liegt nicht unter der lichten Hoehe %3 mm.",
"lg-regel-profil-fehlt": "\n[Lager] Regelprofil %1 nicht gefunden (%2).",
"lg-regel-profil-ungepflegt": "\n[Lager] WARNUNG: Regelprofil %1 ist nicht gepflegt - es gelten die geerbten Werte.",
"lg-regel-unbekannt": "\n[Lager] Regel %1 nicht im Profil.",
+9 -1
View File
@@ -1203,7 +1203,6 @@
"lg-feld-gang": "\nAisle width (mm)",
"lg-feld-tiefe": "\nRack depth (mm)",
"lg-feld-reihen": "\nRows per aisle",
"lg-feld-schienen": "\nRails per aisle",
"lg-feld-q_abstand": "\nCross aisle spacing (mm, 0 = none)",
"lg-feld-q_breite": "\nCross aisle width (mm)",
"lg-feld-richtung": "\nRow direction (degrees)",
@@ -1275,6 +1274,15 @@
"lg-exp-lichte-hoehe-oben": "Level %1 (top): clear height cannot be calculated - set LICHTE_HOEHE_mm.",
"lg-exp-korb-hallenboden": "Area %1 has a mesh basket below the rows, but level %2 is a hall floor - not counted.",
"lg-exp-reihen-ohne-geschoss": "%1 rack row(s) without a known level - not included in the key figures.",
"lg-feld-schienen": "\nTrolley rails per aisle",
"lg-pl-konstr-null": "Level %1 is a platform but has no construction depth (KONSTR_HOEHE_mm = 0).",
"lg-pl-unter-keine": "Level %1: %2 m2 of rack footprint without fall protection (UNTER_REIHE keine) - open area to the level below.",
"lg-pl-lichte-klein": "Level %1: clear height %2 mm below the minimum of %3 mm (%4).",
"lg-pl-gang-schmal": "Level %1: %2 aisle(s) narrower than %4 mm (widths %3 mm; %5).",
"lg-pl-gang-quer": "Level %1: %2 aisle(s) of type gang run across the row direction (ID %3) - cross aisle?",
"lg-pl-gang-neben-randgang": "Level %1: %2 aisle(s) lie directly next to a perimeter aisle (ID %3) - double edge zone?",
"lg-pl-freiraum": "Level %1: no clearance below the goods at hanging level(s) rail/goods (clearance) %2 mm.",
"lg-pl-schiene-ueber-lichte": "Level %1: top rail %2 mm is not below the clear height %3 mm.",
"lg-regel-profil-fehlt": "\n[Storage] Rule profile %1 not found (%2).",
"lg-regel-profil-ungepflegt": "\n[Storage] WARNING: rule profile %1 is not maintained - inherited values apply.",
"lg-regel-unbekannt": "\n[Storage] Rule %1 not in profile.",
+4 -4
View File
@@ -154,7 +154,7 @@
;; --- Einzelne Reihe aendern (Neuaufbau, Kennzeichnung) ---
(setq r0 (car (lg-alle-bloecke "LG_REIHE_*")))
(setq neu (lg-linie-neu-aufbauen r0 (list (cons "LAENGE" "2000") (cons "TIEFE_mm" "700")
(cons "HAENGEEBENEN" "2300/1200") (cons "SCHIENEN" "1")
(cons "HAENGEEBENEN" "2300/1200")
(cons "GESCHOSS" "1") (cons "BEREICH" "1")
(cons "QUELLE" "auto_geaendert"))))
(tlg-eq "reihe neu aufgebaut" "LG_REIHE_2000_700" (if neu (cdr (assoc 2 (entget neu)))))
@@ -174,8 +174,8 @@
(tlg-eq "export konturflaeche" 6.0e7 (ssg-json-get (ssg-json-get eg1 "kontur") "flaeche_mm2"))
(tlg-eq "export konturpunkte" 4 (length (ssg-json-get (ssg-json-get eg1 "kontur") "punkte")))
(tlg-eq "export haengeebenen"
'((("schienenhoehe_mm" . 2300) ("warenlaenge_mm" . 1200))
(("schienenhoehe_mm" . 1100) ("warenlaenge_mm" . 1100)))
'((("schienenhoehe_mm" . 2300) ("warenlaenge_mm" . 1200) ("freiraum_unter_mm" . 0))
(("schienenhoehe_mm" . 1100) ("warenlaenge_mm" . 1100) ("freiraum_unter_mm" . 0)))
(ssg-json-get (vl-some '(lambda (r) (if (= (ssg-json-get r "laenge_mm") 4000) r))
(ssg-json-get daten "reihen"))
"haengeebenen"))
@@ -191,7 +191,7 @@
(tlg-eq "export G1 unter gitterrost" T
(vl-every '(lambda (r) (= (ssg-json-get r "unter_reihe") "gitterrost")) (ssg-json-get daten "reihen")))
(tlg-eq "export lager regallaenge" (ssg-json-get (ssg-json-get eg1 "kennwerte") "regallaenge_mm")
(ssg-json-get (ssg-json-get daten "lager") "regallaenge_mm"))
(ssg-json-get (ssg-json-get (ssg-json-get daten "lager") "summe_alle_geschosse") "regallaenge_mm"))
;; --- Randgaenge Nord + Sued, Schraffur je Belag ---
(setq kb2 (tlg-rechteck 20000.0 0.0 30000.0 6000.0))
+83 -15
View File
@@ -3415,8 +3415,26 @@
(tu-eq "lg-json-wert/obj-arr" "{\"p\": [1, 2.5], \"o\": {\"x\": null}}"
(lg-json-wert (list 'OBJ (cons "p" (list 'ARR 1 2.5)) (cons "o" (list 'OBJ (cons "x" nil))))))
(tu-eq "lg-json-wert/leer" "[]" (lg-json-wert (list 'ARR)))
(tu-eq "lg-j-ebenen" "[{\"schienenhoehe_mm\": 2300, \"warenlaenge_mm\": 1200}]"
(tu-eq "lg-j-ebenen" "[{\"schienenhoehe_mm\": 2300, \"warenlaenge_mm\": 1200, \"freiraum_unter_mm\": 1100}]"
(lg-json-wert (lg-j-ebenen "2300/1200")))
;; nicht zutreffende Felder werden weggelassen, null bleibt null
(tu-eq "lg-json-obj/entfaellt" "{\"a\": 1, \"c\": null}"
(lg-json-obj (list (cons "a" 1) (cons "b" 'ENTFAELLT) (cons "c" nil))))
(tu-eq "lg-json-text/entfaellt" T
(not (vl-string-search "\"b\""
(lg-json-text (cons 'OBJ (cons (cons "b" 'ENTFAELLT)
(mapcar '(lambda (i) (cons (itoa i) i)) '(1 2 3 4 5 6 7 8 9 10 11 12 13))))
""))))
(tu-nil "lg-j/entfaellt" (lg-j (list 'OBJ (cons "b" 'ENTFAELLT)) "b"))
(tu-nil "lg-j/kein-obj" (lg-j 'ENTFAELLT "b"))
;; Freiraum unter der Ware: 2300-1200-1100 = 0, 1100-1100-0 = 0
(tu-eqf "lg-ebenen-freiraum" '((2300.0 1200.0 0.0) (1100.0 1100.0 0.0))
(lg-ebenen-freiraum '((1100.0 1100.0) (2300.0 1200.0))))
(tu-eqf "lg-ebenen-freiraum/luft" '((2400.0 1000.0 300.0) (1100.0 1000.0 100.0))
(lg-ebenen-freiraum '((2400.0 1000.0) (1100.0 1000.0))))
(tu-eq "lg-ausrichtung" '("laengs" "laengs" "quer" "quer" nil)
(list (lg-ausrichtung 90.0 90.0) (lg-ausrichtung 270.0 90.0) (lg-ausrichtung 180.0 90.0)
(lg-ausrichtung 0.0 270.0) (lg-ausrichtung 0.0 nil)))
;; kleine Container einzeilig, grosse je Eintrag eine Zeile
(tu-eq "lg-json-text/klein" "{\"a\": 1}" (lg-json-text (list 'OBJ (cons "a" 1)) ""))
(setq _gross (cons 'OBJ (mapcar '(lambda (i) (cons (itoa i) i)) '(1 2 3 4 5 6 7 8 9 10 11 12 13))))
@@ -3451,10 +3469,19 @@
(list 'OBJ (cons "art" "randgang") (cons "belag" "gitterrost") (cons "laenge_mm" 5000.0) (cons "breite_mm" 800.0))
(list 'OBJ (cons "art" "gang") (cons "belag" "spanplatte") (cons "laenge_mm" 2000.0) (cons "breite_mm" 1000.0))))
(tu-eqf "lg-gaenge-je-art"
'(OBJ ("gang" OBJ ("anzahl" . 2) ("laenge_mm" . 12000.0) ("flaeche_mm2" . 1.2e7))
("quergang" OBJ ("anzahl" . 0) ("laenge_mm" . 0.0) ("flaeche_mm2" . 0.0))
("randgang" OBJ ("anzahl" . 1) ("laenge_mm" . 5000.0) ("flaeche_mm2" . 4.0e6)))
'(OBJ ("gang" OBJ ("anzahl" . 2) ("laenge_mm" . 12000.0) ("flaeche_mm2" . 1.2e7) ("anzahl_quer" . 0)
("nach_breite" ARR (OBJ ("breite_mm" . 1000.0) ("anzahl" . 2) ("laenge_mm" . 12000.0) ("flaeche_mm2" . 1.2e7))))
("quergang" OBJ ("anzahl" . 0) ("laenge_mm" . 0.0) ("flaeche_mm2" . 0.0) ("anzahl_quer" . 0)
("nach_breite" ARR))
("randgang" OBJ ("anzahl" . 1) ("laenge_mm" . 5000.0) ("flaeche_mm2" . 4.0e6) ("anzahl_quer" . 0)
("nach_breite" ARR (OBJ ("breite_mm" . 800.0) ("anzahl" . 1) ("laenge_mm" . 5000.0) ("flaeche_mm2" . 4.0e6)))))
(lg-gaenge-je-art _ga))
;; Breiten getrennt, quer liegende gezaehlt
(setq _gq (lg-gaenge-je-art
(list (list 'OBJ (cons "art" "gang") (cons "laenge_mm" 10000.0) (cons "breite_mm" 1000.0) (cons "ausrichtung" "laengs"))
(list 'OBJ (cons "art" "gang") (cons "laenge_mm" 25200.0) (cons "breite_mm" 3600.0) (cons "ausrichtung" "quer")))))
(tu-eq "lg-gaenge-je-art/quer" 1 (lg-j (lg-j _gq "gang") "anzahl_quer"))
(tu-eq "lg-gaenge-je-art/breiten" 2 (length (cdr (lg-j (lg-j _gq "gang") "nach_breite"))))
;; Geschoss 1 (Spanplatte, 3100) unter Geschoss 2 (6100, Konstr. 250)
(setq _g1 (list 'OBJ (cons "nr" 1) (cons "hoehe_belag_mm" 3100.0) (cons "konstr_hoehe_mm" 250.0)
(cons "lichte_hoehe_mm" nil) (cons "belag_art" "spanplatte")
@@ -3465,7 +3492,9 @@
(tu-eqf "lg-kennwerte/lichte-berechnet" 2750.0 (lg-j _kw "lichte_hoehe_mm"))
(tu-eqf "lg-kennwerte/regallaenge" 6000.0 (lg-j _kw "regallaenge_mm"))
(tu-eqf "lg-kennwerte/grundflaeche" 4.2e6 (lg-j _kw "regalgrundflaeche_mm2"))
(tu-eqf "lg-kennwerte/schienen" 8000.0 (lg-j _kw "schienenlaenge_mm"))
;; Regalrohr = Laenge x Haengeebenen: 4000 x 2 + 2000 x 1
(tu-eqf "lg-kennwerte/regalrohr" 10000.0 (lg-j _kw "regalrohrlaenge_mm"))
(tu-eqf "lg-kennwerte/ohne-absturz" 0.0 (lg-j _kw "ohne_absturzsicherung_mm2"))
(tu-eqf "lg-kennwerte/belag-gaenge" 1.2e7 (lg-j _kw "belagsflaeche_mm2"))
;; Gitterrost = Randgang gitterrost 4e6 + Reihen 4.2e6
(tu-eqf "lg-kennwerte/gitterrost" 8.2e6 (lg-j _kw "gitterrostflaeche_mm2"))
@@ -3477,13 +3506,20 @@
(tu-eqf "lg-kennwerte/belag-kontur" (- 6.0e7 4.2e6) (lg-j _kw "belagsflaeche_mm2"))
(tu-nil "lg-kennwerte/lichte-oben" (lg-j _kw "lichte_hoehe_mm"))
(tu-eqf "lg-kennwerte/lichte-vorgabe" 2800.0
(lg-j (car (lg-kennwerte-geschoss (lg-j-setzen _g1 "lichte_hoehe_mm" 2800.0) _g2 nil nil 0))
(lg-j (car (lg-kennwerte-geschoss (lg-j-setzen _g1 "lichte_hoehe_vorgabe_mm" 2800.0) _g2 nil nil 0))
"lichte_hoehe_mm"))
;; Hallenboden: keine Buehne, keine Flaechen
;; Reihe ohne Absturzsicherung auf der Buehne
(tu-eqf "lg-kennwerte/ohne-absturz-keine" 2.8e6
(lg-j (car (lg-kennwerte-geschoss _g1 _g2 (list (lg-j-setzen _r1 "unter_reihe" "keine")) nil 1))
"ohne_absturzsicherung_mm2"))
;; Hallenboden: keine Buehne, Flaechen entfallen (werden nicht geschrieben)
(setq _kw (car (lg-kennwerte-geschoss (lg-j-setzen _g1 "belag_art" "hallenboden") _g2 (list _r1) _ga 1)))
(tu-eq "lg-kennwerte/hallenboden" 'FALSE (lg-j _kw "buehne"))
(tu-nil "lg-kennwerte/hallenboden-belag" (lg-j _kw "belagsflaeche_mm2"))
(tu-nil "lg-kennwerte/hallenboden-gitter" (lg-j _kw "gitterrostflaeche_mm2"))
(tu-nil "lg-kennwerte/hallenboden-korb" (lg-j _kw "gitterkorb"))
(tu-eq "lg-kennwerte/hallenboden-entfaellt" T
(not (vl-string-search "belagsflaeche" (lg-json-wert _kw))))
;; --- Gitterkorb: offene Kanten ---
;; Einzelreihe 4000 x 700: alles offen
@@ -3520,16 +3556,48 @@
(tu-eqf "lg-kennwerte/korb-seite" (* 500.0 5400.0) (lg-j (lg-j _kw "gitterkorb") "seitenflaeche_mm2"))
(tu-eq "lg-kennwerte/korb-reihen" 1 (lg-j (lg-j _kw "gitterkorb") "reihen"))
(tu-eqf "lg-kennwerte/korb-kein-gitterrost" 0.0 (lg-j _kw "gitterrostflaeche_mm2"))
;; Lager-Summen ueber zwei Geschosse
;; Lager-Summen ueber zwei Geschosse; die Grundrisse liegen im Plan
;; nebeneinander - grundriss_max ist der groesste, keine gemeinsame Huelle
(setq _g1b (lg-j-setzen _g1 "kontur" (list 'OBJ (cons "bbox" (list 'ARR 0.0 0.0 10000.0 6000.0))))
_g2b (lg-j-setzen _g2 "kontur" (list 'OBJ (cons "bbox" (list 'ARR 0.0 50000.0 12000.0 55000.0)))))
(tu-eqf "lg-kennwerte/huelle-geschoss" '(10000.0 6000.0)
(list (lg-j (lg-j (car (lg-kennwerte-geschoss _g1b _g2b nil nil 1)) "huelle") "laenge_mm")
(lg-j (lg-j (car (lg-kennwerte-geschoss _g1b _g2b nil nil 1)) "huelle") "breite_mm")))
(setq _kl (lg-kennwerte-lager
(list (lg-j-setzen (lg-j-setzen _g1 "kennwerte" (car (lg-kennwerte-geschoss _g1 _g2 (list _r1) nil 1)))
"kontur" (list 'OBJ (cons "bbox" (list 'ARR 0.0 0.0 10000.0 6000.0))))
(lg-j-setzen (lg-j-setzen _g2 "kennwerte" (car (lg-kennwerte-geschoss _g2 nil (list _r2) nil 1)))
"kontur" (list 'OBJ (cons "bbox" (list 'ARR 0.0 0.0 12000.0 5000.0)))))
(list (lg-j-setzen _g1b "kennwerte" (car (lg-kennwerte-geschoss _g1b _g2b (list _r1) nil 1)))
(lg-j-setzen _g2b "kennwerte" (car (lg-kennwerte-geschoss _g2b nil (list _r2) nil 1))))
(list _r1 _r2) nil 2))
(tu-eqf "lg-kennwerte-lager/regal" 6000.0 (lg-j _kl "regallaenge_mm"))
(tu-eqf "lg-kennwerte-lager/huelle" '(12000.0 6000.0)
(list (lg-j (lg-j _kl "huelle") "laenge_mm") (lg-j (lg-j _kl "huelle") "breite_mm")))
(tu-eqf "lg-kennwerte-lager/regal" 6000.0 (lg-j (lg-j _kl "summe_alle_geschosse") "regallaenge_mm"))
(tu-eqf "lg-kennwerte-lager/grundriss-max" '(12000.0 6000.0)
(list (lg-j (lg-j _kl "grundriss_max") "laenge_mm") (lg-j (lg-j _kl "grundriss_max") "breite_mm")))
;; --- Plausibilitaet ---
(setq _grenzen '(("gang_min" 750.0 "Q1") ("lichte_min" 2000.0 "Q2")))
;; alles daneben: 8 Warnungen
(setq _pw (lg-plausibilitaet
(list 'OBJ (cons "nr" 2) (cons "belag_art" "spanplatte") (cons "konstr_hoehe_mm" 0.0))
(list 'OBJ (cons "lichte_hoehe_mm" 1800.0) (cons "ohne_absturzsicherung_mm2" 1.0e6))
(list (list 'OBJ (cons "haengeebenen" (lg-j-ebenen "2300/1200;1100/1100"))))
(list (list 'OBJ (cons "id" "GQ") (cons "art" "gang") (cons "ausrichtung" "quer") (cons "breite_mm" 500.0)
(cons "ecken" (lg-j-pkte '((0.0 0.0) (10000.0 0.0) (10000.0 500.0) (0.0 500.0)))))
(list 'OBJ (cons "id" "RG") (cons "art" "randgang") (cons "breite_mm" 1600.0)
(cons "ecken" (lg-j-pkte '((0.0 500.0) (10000.0 500.0) (10000.0 2100.0) (0.0 2100.0))))))
_grenzen))
(tu-eq "lg-plausibilitaet/alle" 8 (length _pw))
;; sauber: keine Warnung
(tu-nil "lg-plausibilitaet/sauber"
(lg-plausibilitaet
(list 'OBJ (cons "nr" 2) (cons "belag_art" "spanplatte") (cons "konstr_hoehe_mm" 250.0))
(list 'OBJ (cons "lichte_hoehe_mm" 3000.0) (cons "ohne_absturzsicherung_mm2" 0.0))
(list (list 'OBJ (cons "haengeebenen" (lg-j-ebenen "2400/1000;1100/1000"))))
(list (list 'OBJ (cons "id" "G") (cons "art" "gang") (cons "ausrichtung" "laengs") (cons "breite_mm" 1000.0)
(cons "ecken" (lg-j-pkte '((0.0 0.0) (10000.0 0.0) (10000.0 1000.0) (0.0 1000.0))))))
_grenzen))
;; Hallenboden: Konstruktionshoehe 0 ist dort kein Fehler
(tu-nil "lg-plausibilitaet/hallenboden"
(lg-plausibilitaet (list 'OBJ (cons "nr" 1) (cons "belag_art" "hallenboden") (cons "konstr_hoehe_mm" 0.0))
(list 'OBJ (cons "lichte_hoehe_mm" 3000.0)) nil nil _grenzen))
(tu-eq "lg-unikat" '("a" "b") (lg-unikat '("a" "b" "a")))
;; --- Regelprofil-Aufloesung ---
(tu-eq "lg-bedingung/leer" 'ja (lg-bedingung-pruefen nil nil))