Personen-Belegung pro Raum + Stempel-Aggregation

Architekten-Workflow: bei Schulen/Buero/Versammlungsstaetten muss die
Personenzahl pro Raum erfasst werden (SIA: m²/Person als Indikator).

Backend:
- UserString dossier_raum_personen (int)
- _attach_meta + _read_meta + state-emit
- _update_wall raum-Branch akzeptiert "personen" im Patch
- compute_sia_bilanz aggregiert personen-Summe ueber Scope
- Stempel: neue Show-Flag stempel_show_personen (default false) +
  Bilanz-Renderer-Zeile "N Personen"
- Stempel-Stil-Field showPersonen mit dabei

Frontend (RaumProperties):
- Personen-Input (number, min 0) zwischen Funktion + Layout-Builder
- Nur sichtbar bei normalen Raeumen (nicht GF/AGF)
- Live-Anzeige "m²/Person" Suffix wenn area + personen > 0
  → User sieht sofort ob die Belegung sinnvoll ist (SIA-Vergleich)

Frontend (StempelProperties):
- Neuer Show-Toggle "Personen" (default off)
- Live-Vorschau zeigt Personen-Summe wenn aktiv + > 0
- _OFF_BY_DEFAULT Set generalisiert Default-Handling (showCount, showPersonen)
This commit is contained in:
2026-05-27 01:08:58 +02:00
parent 1c3b0f3919
commit e2d66a5d64
2 changed files with 84 additions and 11 deletions
+37 -6
View File
@@ -2722,7 +2722,8 @@ def _attach_meta(obj_attrs, wall_id, type_, geschoss, dicke, uk_over, ok_over,
stempel_show_nf=None, stempel_show_vf=None,
stempel_show_ff=None, stempel_show_ngf=None,
stempel_show_gf=None, stempel_show_agf=None,
stempel_show_count=None, stempel_show_seps=None,
stempel_show_count=None, stempel_show_personen=None,
stempel_show_seps=None,
stempel_stil_id=None,
wand_layered=None, wand_layers=None, wand_layer_idx=None,
wand_chain_members=None,
@@ -2962,6 +2963,7 @@ def _attach_meta(obj_attrs, wall_id, type_, geschoss, dicke, uk_over, ok_over,
(_KEY_STEMPEL_SHOW_GF, stempel_show_gf),
(_KEY_STEMPEL_SHOW_AGF, stempel_show_agf),
(_KEY_STEMPEL_SHOW_COUNT, stempel_show_count),
(_KEY_STEMPEL_SHOW_PERS, stempel_show_personen),
(_KEY_STEMPEL_SHOW_SEPS, stempel_show_seps),
):
if _v is not None:
@@ -3200,6 +3202,7 @@ def _read_meta(obj):
st_show_gf = _sh_on(_KEY_STEMPEL_SHOW_GF, True)
st_show_agf = _sh_on(_KEY_STEMPEL_SHOW_AGF, True)
st_show_count = _sh_on(_KEY_STEMPEL_SHOW_COUNT, False)
st_show_pers = _sh_on(_KEY_STEMPEL_SHOW_PERS, False)
st_show_seps = _sh_on(_KEY_STEMPEL_SHOW_SEPS, True)
st_stil_id = a.GetUserString(_KEY_STEMPEL_STIL_ID) or ""
# Field-Layout — parsed JSON list of rows
@@ -3311,6 +3314,7 @@ def _read_meta(obj):
"raum_align": r_align,
"raum_sia": r_sia,
"raum_fuellung": r_fuell,
"raum_personen": r_personen,
"raum_txt_font": r_font,
"raum_txt_bold": r_bold,
"raum_txt_italic": r_ital,
@@ -3340,6 +3344,7 @@ def _read_meta(obj):
"stempel_show_gf": st_show_gf,
"stempel_show_agf": st_show_agf,
"stempel_show_count": st_show_count,
"stempel_show_personen": st_show_pers,
"stempel_show_seps": st_show_seps,
"stempel_stil_id": st_stil_id,
"wand_layered": w_layered,
@@ -3978,6 +3983,7 @@ _KEY_STEMPEL_SHOW_NGF = "dossier_stempel_show_ngf" # default "1"
_KEY_STEMPEL_SHOW_GF = "dossier_stempel_show_gf" # default "1"
_KEY_STEMPEL_SHOW_AGF = "dossier_stempel_show_agf" # default "1"
_KEY_STEMPEL_SHOW_COUNT = "dossier_stempel_show_count" # default "0"
_KEY_STEMPEL_SHOW_PERS = "dossier_stempel_show_pers" # default "0"
_KEY_STEMPEL_SHOW_SEPS = "dossier_stempel_show_seps" # default "1"
_KEY_STEMPEL_STIL_ID = "dossier_stempel_stil_id" # aktiver Stil
# Storage-Key fuer Stempel-Stile (Presets, per Doc)
@@ -3985,7 +3991,8 @@ _KEY_STEMPEL_STILE = "dossier_stempel_stile"
_STEMPEL_STIL_FIELDS = (
"header", "showScope",
"showHnf", "showNnf", "showNf", "showVf", "showFf",
"showNgf", "showGf", "showAgf", "showCount", "showSeparators",
"showNgf", "showGf", "showAgf", "showCount", "showPersonen",
"showSeparators",
"font", "bold", "italic", "txtH",
)
@@ -5160,7 +5167,7 @@ def compute_sia_bilanz(doc, scope="total"):
laut SIA 416).
"""
out = {"hnf": 0.0, "nnf": 0.0, "vf": 0.0, "ff": 0.0,
"gf": 0.0, "agf": 0.0, "count": 0,
"gf": 0.0, "agf": 0.0, "count": 0, "personen": 0,
"scope": scope, "geschossName": ""}
if doc is None: return out
target_gid = None
@@ -5181,6 +5188,8 @@ def compute_sia_bilanz(doc, scope="total"):
if sia not in ("hnf", "nnf", "vf", "ff", "gf", "agf"): continue
out[sia] += float(area)
out["count"] += 1
try: out["personen"] += int(m.get("raum_personen", 0) or 0)
except Exception: pass
except Exception: pass
out["nf"] = out["hnf"] + out["nnf"]
out["ngf"] = out["nf"] + out["vf"] + out["ff"]
@@ -5188,7 +5197,8 @@ def compute_sia_bilanz(doc, scope="total"):
def _format_bilanz_lines(bilanz, rundung="0.1", visibility=None,
show_separators=True, show_count=False):
show_separators=True, show_count=False,
show_personen=False):
"""Baut die Stempel-Textzeilen aus einer Bilanz. Zeigt nur Kategorien
mit Flaeche > 0 UND deren visibility-Flag True ist.
@@ -5231,6 +5241,11 @@ def _format_bilanz_lines(bilanz, rundung="0.1", visibility=None,
if show_count and bilanz.get("count", 0) > 0:
if show_separators and lines: lines.append(sep)
lines.append("{} Räume".format(bilanz["count"]))
# Personen-Total optional (Summe ueber alle Raeume im Scope)
if show_personen and bilanz.get("personen", 0) > 0:
if not (show_count and show_separators) and show_separators and lines:
lines.append(sep)
lines.append("{} Personen".format(bilanz["personen"]))
return lines
@@ -5238,6 +5253,7 @@ def _make_stempel_text(pos, scope, doc, text_height=0.20, z=0.0,
font=None, bold=False, italic=False,
header_text="Nutzflächen", show_scope=True,
show_separators=True, show_count=False,
show_personen=False,
visibility=None):
"""Baut die Stempel-TextEntity fuer einen Scope ("total" oder
"geschoss:<id>"). header_text + show_* steuern Layout-Customisation.
@@ -5262,7 +5278,8 @@ def _make_stempel_text(pos, scope, doc, text_height=0.20, z=0.0,
header = " · ".join(header_parts) if header_parts else ""
body = _format_bilanz_lines(bilanz, visibility=visibility,
show_separators=show_separators,
show_count=show_count)
show_count=show_count,
show_personen=show_personen)
if not body:
body = ["(keine klassifizierten Räume)"]
lines = []
@@ -6771,6 +6788,7 @@ def _regenerate_element_body(doc, element_id, src_obj, meta, geom, geschoss_name
show_scope=bool(meta.get("stempel_show_scope", True)),
show_separators=bool(meta.get("stempel_show_seps", True)),
show_count=bool(meta.get("stempel_show_count", False)),
show_personen=bool(meta.get("stempel_show_personen", False)),
visibility=visibility)
if new_te is None: return False
# In-place replace
@@ -7144,6 +7162,7 @@ class ElementeBridge(panel_base.BaseBridge):
"layout": meta.get("raum_layout") or [],
"txtModus": meta.get("raum_txt_modus", "fix"),
"stilId": meta.get("raum_stil_id", ""),
"personen": int(meta.get("raum_personen", 0) or 0),
"area": area,
"areaFmt": _format_area(area, rnd_eff),
"umfang": perim,
@@ -7174,6 +7193,7 @@ class ElementeBridge(panel_base.BaseBridge):
"showGf": bool(meta.get("stempel_show_gf", True)),
"showAgf": bool(meta.get("stempel_show_agf", True)),
"showCount": bool(meta.get("stempel_show_count", False)),
"showPersonen": bool(meta.get("stempel_show_personen", False)),
"showSeparators": bool(meta.get("stempel_show_seps", True)),
"stilId": meta.get("stempel_stil_id", ""),
"bilanz": bilanz,
@@ -11015,6 +11035,13 @@ class ElementeBridge(panel_base.BaseBridge):
old_meta.get("raum_show_area", True)))
r_show_sia = bool(p.get("showSia",
old_meta.get("raum_show_sia", False)))
# Personen-Belegung (int, default 0)
try:
r_personen = int(p.get("personen",
old_meta.get("raum_personen", 0)))
except Exception:
r_personen = int(old_meta.get("raum_personen", 0) or 0)
if r_personen < 0: r_personen = 0
# Layout: Liste-of-Rows aus Frontend (JSON-serializable). Wenn
# nicht im Patch → vom alten meta uebernehmen.
r_layout = p.get("layout", old_meta.get("raum_layout", []))
@@ -11072,7 +11099,8 @@ class ElementeBridge(panel_base.BaseBridge):
raum_show_area=r_show_are,
raum_show_sia=r_show_sia,
raum_layout=r_layout,
raum_txt_modus=r_modus)
raum_txt_modus=r_modus,
raum_personen=r_personen)
axis_obj.Attributes = attrs
axis_obj.CommitChanges()
_save_last(raum_name_last=r_name, raum_rundung=r_rnd,
@@ -11123,6 +11151,8 @@ class ElementeBridge(panel_base.BaseBridge):
old_meta.get("stempel_show_agf", True)))
st_show_count = bool(p.get("showCount",
old_meta.get("stempel_show_count", False)))
st_show_pers = bool(p.get("showPersonen",
old_meta.get("stempel_show_personen", False)))
st_show_seps = bool(p.get("showSeparators",
old_meta.get("stempel_show_seps", True)))
attrs = axis_obj.Attributes
@@ -11142,6 +11172,7 @@ class ElementeBridge(panel_base.BaseBridge):
stempel_show_gf=st_show_gf,
stempel_show_agf=st_show_agf,
stempel_show_count=st_show_count,
stempel_show_personen=st_show_pers,
stempel_show_seps=st_show_seps)
axis_obj.Attributes = attrs
axis_obj.CommitChanges()