diff --git a/docs/architektur/modulkarte.md b/docs/architektur/modulkarte.md index 4e01f1a..a74b35a 100644 --- a/docs/architektur/modulkarte.md +++ b/docs/architektur/modulkarte.md @@ -26,7 +26,7 @@ Legende: ⚠ = über 600 Zeilen, nie komplett laden, per `grep -n "def "` navigi |---|---:|---| | `functions/__init__.py` | 50 | Re-Export vieler Wrapper (`from sn_basis.functions import QgsProject, info, ...`) | | `functions/qt_wrapper.py` ⚠ | 832 | Qt-Symbole: PyQt6 primär, PyQt5-Fallback, sonst Mock. `QT_VERSION` (0/5/6), Enum-Aliase (`DockAreaRight`, …), `exec_dialog()` | -| `functions/qgiscore_wrapper.py` ⚠ | 1 382 | `qgis.core`-Symbole und Konstanten; ab Zeile ~255 Mock-Klassen; eigener Block für Vektorkacheln/Ausdrücke/Legende (#88); Helfer `network_head`, `get_layer_extent`, `create_buffer_layer`, `layer_exists_in_gpkg`, `polygon_zu_linie` | +| `functions/qgiscore_wrapper.py` ⚠ | 1 428 | `qgis.core`-Symbole und Konstanten; ab Zeile ~255 Mock-Klassen; eigener Block für Vektorkacheln/Ausdrücke/Legende (#88); Helfer `network_head`, `get_layer_extent`, `create_buffer_layer`, `layer_exists_in_gpkg`, `polygon_zu_linie` | | `functions/qgisui_wrapper.py` | 258 | `iface`-Zugriffe: Hauptfenster, Docks, Menüs, Toolbars, Layoutdesigner; Mock-`iface` | | `functions/dialog_wrapper.py` | 521 | Dialoge: `ask_yes_no`, `show_info_dialog`, `ask_text`, Überschreiben/Anhängen/Abbrechen, `ProgressDialog`/`create_progress_dialog`, `ask_mehrfachauswahl` (Liste mit Häkchen) | | `functions/message_wrapper.py` | 85 | MessageBar: `info`, `warning`, `error`, `success`, `push_message` | @@ -57,7 +57,8 @@ Legende: ⚠ = über 600 Zeilen, nie komplett laden, per `grep -n "def "` navigi | `modules/LayerLoader.py` | 422 | `create_layer(provider, link, thema)`, `apply_style`, `filter_by_extent`, `filter_by_layer`, `add_to_project` | | `modules/Datenschreiber.py` | 448 | `schreibe_Daten(...)` in GeoPackage, `lade_Layer(...)` ins Projekt, `schreibe_log(...)` HTML-Protokoll | | `modules/print_logic.py` ⚠ | 1 360 | `PrintLogic`, `AtlasConfig`, `RectangleCaptureTool`: Druckbereich, Maßstab, Atlas, Layoutaufruf | -| `modules/print_layout.py` ⚠ | 1 111 | `PrintLayout`: Layoutaufbau für § 38 / § 41 (Karte, Legende, Gitter, Schriftfeld) | +| `modules/print_layout.py` ⚠ | 1 127 | `PrintLayout`: Layoutaufbau für § 38 / § 41 (Karte, Legende, Gitter, Schriftfeld) | +| `modules/print_kartenrand.py` | 189 | Kartenrand (Legenden, Quellenangabe, Kartenschild) überlappungsfrei anordnen: 1–3 Legendenspalten, Rand breiter, Seite ggf. höher (#93) | | `modules/print_layout_baufreigabe.py` | 403 | Layout „Anlage zur Baufreigabe“ (feste DIN A3/A4 quer) | | `modules/basemap_legende.py` | 471 | Basemap-Legende (#88): Legendenkatalog laden, Styles → Einträge, Auswahl merken, Basemap-Layer erkennen, Auswertebereich; `BasemapLegende.aktualisiere(layout)` als Einstieg | | `modules/basemap_kacheln.py` | 192 | Kacheln des Basemap-Layers kachelweise über `selectByGeometry` auswerten, Renderer-Styles lesen, Zoomstufen wie der QGIS-Renderer | @@ -139,8 +140,8 @@ Dient als **minimales Muster** für ein neues Fachplugin (Skill `sn-neues-fachpl | `sn_verfahrensgebiet/functions/grenzpunkt_alkis.py` | 1 674 | | `sn_basis/modules/print_logic.py` | 1 360 | | `sn_plan41/ui/tab_a_logic.py` | 1 239 | -| `sn_basis/functions/qgiscore_wrapper.py` | 1 382 | -| `sn_basis/modules/print_layout.py` | 1 111 | +| `sn_basis/functions/qgiscore_wrapper.py` | 1 428 | +| `sn_basis/modules/print_layout.py` | 1 127 | | `sn_verfahrensgebiet/functions/verfahrensgebiet_shape_komplett.py` | 978 | | `sn_verfahrensgebiet/ui/tabs/working_tab.py` | 873 | | `sn_verfahrensgebiet/functions/knickpunkt_pruefung.py` | 810 | diff --git a/docs/architektur/schnittstellen.md b/docs/architektur/schnittstellen.md index dc8eafa..41a4768 100644 --- a/docs/architektur/schnittstellen.md +++ b/docs/architektur/schnittstellen.md @@ -151,3 +151,13 @@ flowchart LR `sn_basis/basemap_standardstil`. - **Neue öffentliche Funktion:** `dialog_wrapper.ask_mehrfachauswahl(titel, hinweis, eintraege, vorauswahl)` – Liste mit Häkchen, Gruppen, Suche; liefert gewählte Schlüssel oder `None` bei Abbruch. + +## 12. Kartenrand im Standardlayout (Basis #93) + +`print_kartenrand.ordne_kartenrand_an(layout)` läuft am Ende von `PrintLayout.create_single_page_layout` und findet +die Elemente **über ihre IDs**: `Hauptkarte`, `Legende`, `Legende Basemap`, `Quellenangabe`, `Kartenschild`, +`Kartenschild_Linie_1` … `_6` und die Schriftfeld-Beschriftungen (`Herausgeber` … `Aktenzeichen`, Liste +`UNTERE_ELEMENTE`). Wer im Layoutaufbau eine dieser IDs ändert oder ein neues Element unter die Legenden setzt, +muss die Liste anpassen. Die Seitengröße aus `print_logic` ist danach nur noch eine Mindestgröße: Breite und Höhe +können wachsen, die Karte bleibt bei 10 mm / 10 mm mit unveränderter Größe. + diff --git a/docs/status/STATUS.md b/docs/status/STATUS.md index 0a46a38..8cc95c4 100644 --- a/docs/status/STATUS.md +++ b/docs/status/STATUS.md @@ -64,10 +64,12 @@ spätere Phase und beginnt erst, wenn die Test-Baseline grün ist und das Projek `sql=`-Filtern). Vergleich 6↔7 und Anpassungsliste: `docs/konzept/09_alkis7_umstellung.md`. Nächster Schritt: Gitea-Issue in `Plugin_SN_Verfahrensgebiet`. 15. **Basemap-Legende im Druck (Basis #88).** In `unstable` gemergt: #88 (PR #89), Punktlinien-Korrektur #90 - (PR #91). Rand für weiße Flächen (#92) auf `Plugin_SN_Basis:bugfix/92-basemap-legende-weisse-flaechen`, - PR steht aus. Offen: **fachliche Abnahme des Legendenkatalogs** `sn_basis/data/basemap_legende.json` + (PR #91), Rand für weiße Flächen #92. Offen: **fachliche Abnahme des Legendenkatalogs** `sn_basis/data/basemap_legende.json` (Bezeichnungen, Gruppen, Zusammenfassungen; Konzept `docs/konzept/10_basemap_legende.md` Abschnitt 10, - ADR 0010) und Test unter QGIS 4. + ADR 0010; bisher unauffällig). Unter QGIS 4 geprüft (Plugin funktioniert, Rückmeldung 02.10.2026). +16. **Kartenrand-Überlappung bei kleinen Verfahren (Basis #93).** Umgesetzt auf + `Plugin_SN_Basis:bugfix/93-kartenrand-ueberlappung`, PR steht aus. Offen: Basemap-Legende wird dreispaltig sehr + breit (alle Spalten so breit wie der längste Text) – ggf. ungleiche Spaltenbreiten prüfen. **Hinweis zum lokalen Stand (04.09.2026):** Die Klone `Plugin_SN_Verfahrensgebiet` (4 Commits: PR #43, PR #45) und `Repository` (Release 26.8.4-unstable) liegen hinter `origin`. Aktualisieren mit `python scripts/hallo.py`. diff --git a/docs/tests/testkatalog.html b/docs/tests/testkatalog.html index 081daab..785e557 100644 --- a/docs/tests/testkatalog.html +++ b/docs/tests/testkatalog.html @@ -119,20 +119,20 @@ Testkatalog der sn_*-Plugins — was die Suite heute prüft, auf einen Blick.
Quelle: docs/tests/testkatalog.md
Baseline: docs/status/testbaseline.json (SHA-256 aeabc946a7f3)
-
662Testfälle
-
619grün
+
672Testfälle
+
629grün
35rot (Baseline)
78%mit Docstring
-
57Testdateien
+
58Testdateien
Verteilung je Paket
-
sn_basis40 Dateien · 410 Testfälle
+
sn_basis41 Dateien · 420 Testfälle
sn_verfahrensgebiet12 Dateien · 208 Testfälle
sn_plan415 Dateien · 44 Testfälle
@@ -147,9 +147,9 @@

sn_basis

-

Plattform-Plugin · Ordner Plugin_SN_Basis · 40 Testdateien · 410 Testfälle

+

Plattform-Plugin · Ordner Plugin_SN_Basis · 41 Testdateien · 420 Testfälle

- @@ -934,7 +934,40 @@ classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420; classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20; classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08; - classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
IsCaseSensitiveFsTests
test_windows_ist_nicht_case_sensitiv
Prüft, dass Windows als nicht case-sensitives Dateisystem gilt.grün
IsCaseSensitiveFsTests
test_macos_ist_nicht_case_sensitiv
Prüft, dass macOS als nicht case-sensitives Dateisystem gilt.grün
IsCaseSensitiveFsTests
test_linux_ist_case_sensitiv
Prüft, dass Linux als case-sensitives Dateisystem gilt.grün

— (Docstring fehlt)

TestPrintLayout 5
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
IsCaseSensitiveFsTests
test_windows_ist_nicht_case_sensitiv
Prüft, dass Windows als nicht case-sensitives Dateisystem gilt.grün
IsCaseSensitiveFsTests
test_macos_ist_nicht_case_sensitiv
Prüft, dass macOS als nicht case-sensitives Dateisystem gilt.grün
IsCaseSensitiveFsTests
test_linux_ist_case_sensitiv
Prüft, dass Linux als case-sensitives Dateisystem gilt.grün

Tests für modules/print_kartenrand.py – Anordnung des Kartenrands neben der Karte (Basis #93).

TestBerechneAnordnung 5TestOrdneKartenrandAn 3TestAnbindungPrintLayout 2
flowchart TD
+  root(["test_print_kartenrand.py"])
+  class root rootnode
+  root --> g1["TestBerechneAnordnung (5)"]
+  class g1 groupnode
+  g1 --> t1("passt_einspaltig_nichts_aendert_sich")
+  g1 --> t2("mehr_spalten_und_breiterer_rand")
+  g1 --> t3("seite_wird_hoeher_wenn_auch_drei_spalten_nicht_reichen")
+  g1 --> t4("seite_wird_nie_kleiner")
+  g1 --> t5("ohne_legenden_nur_kartenschild")
+  root --> g2["TestOrdneKartenrandAn (3)"]
+  class g2 groupnode
+  g2 --> t6("seite_hoeher_und_kartenschild_verschoben")
+  g2 --> t7("passt_nichts_wird_verschoben")
+  g2 --> t8("ohne_karte_keine_anordnung")
+  root --> g3["TestAnbindungPrintLayout (2)"]
+  class g3 groupnode
+  g3 --> t9("vorlage_ordnet_kartenrand_an")
+  g3 --> t10("fehler_bei_der_anordnung_verhindert_die_vorlage_nicht")
+  class t1 ok
+  class t2 ok
+  class t3 ok
+  class t4 ok
+  class t5 ok
+  class t6 ok
+  class t7 ok
+  class t8 ok
+  class t9 ok
+  class t10 ok
+  classDef rootnode fill:#1f4038,stroke:#16302a,stroke-width:1px,color:#f4f1e8,font-weight:600;
+  classDef groupnode fill:#cfe0da,stroke:#5c8a7d,stroke-width:1px,color:#152420;
+  classDef ok fill:#dcefdc,stroke:#3f7d4a,stroke-width:1px,color:#1c3a20;
+  classDef warn fill:#f6ead9,stroke:#b5722a,stroke-width:1px,color:#4a2c08;
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestBerechneAnordnung
test_passt_einspaltig_nichts_aendert_sich
Prüft, dass bei genug Platz neben der Karte einspaltig angeordnet wird und Seite und Kartenschild bleiben.grün
TestBerechneAnordnung
test_mehr_spalten_und_breiterer_rand
Prüft, dass bei zu hohen Legenden die kleinste passende Spaltenzahl gewählt und der Kartenrand dafür verbreitert wird.grün
TestBerechneAnordnung
test_seite_wird_hoeher_wenn_auch_drei_spalten_nicht_reichen
Prüft, dass die Seite höher wird und Quellenangabe und Kartenschild nach unten rutschen, wenn auch drei Spalten nicht reichen.grün
TestBerechneAnordnung
test_seite_wird_nie_kleiner
Prüft, dass Seitenbreite und -höhe nie unter die ursprüngliche Seitengröße fallen.grün
TestBerechneAnordnung
test_ohne_legenden_nur_kartenschild
Prüft, dass ohne Legenden nur Quellenangabe und Kartenschild zählen und die Seite bei zu niedriger Karte höher wird.grün
TestOrdneKartenrandAn
test_seite_hoeher_und_kartenschild_verschoben
Prüft, dass bei zu niedriger Karte die Legende dreispaltig wird, die Seite wächst und Quellenangabe und Kartenschild um denselben Betrag nach unten rutschen.grün
TestOrdneKartenrandAn
test_passt_nichts_wird_verschoben
Prüft, dass bei ausreichend hoher Karte weder Seite noch Kartenschild verändert werden.grün
TestOrdneKartenrandAn
test_ohne_karte_keine_anordnung
Prüft, dass ein Layout ohne Hauptkarte unverändert bleibt.grün
TestAnbindungPrintLayout
test_vorlage_ordnet_kartenrand_an
Prüft, dass PrintLayout beim Anlegen einer Vorlage den Kartenrand anordnen lässt.grün
TestAnbindungPrintLayout
test_fehler_bei_der_anordnung_verhindert_die_vorlage_nicht
Prüft, dass ein Fehler bei der Anordnung nur als Warnung gemeldet wird und keine Ausnahme durchreicht.grün

— (Docstring fehlt)

TestPrintLayout 5
flowchart TD
   root(["test_print_layout.py"])
   class root rootnode
   root --> g1["TestPrintLayout (5)"]
diff --git a/docs/tests/testkatalog.md b/docs/tests/testkatalog.md
index 3b7934c..c2ce7a1 100644
--- a/docs/tests/testkatalog.md
+++ b/docs/tests/testkatalog.md
@@ -9,17 +9,17 @@ selbst (Docstrings) und aus der Testbaseline.
 
 Stand der Baseline: `docs/status/testbaseline.json` (SHA-256 `aeabc946a7f3`)
 
-Gesamt: 3 Pakete, 57 Testdateien, 662 Testfälle – 619 grün, 35 rot (Baseline), 8 übersprungen.
-Mit Beschreibung (Docstring): 517 von 662 (78 %).
+Gesamt: 3 Pakete, 58 Testdateien, 672 Testfälle – 629 grün, 35 rot (Baseline), 8 übersprungen.
+Mit Beschreibung (Docstring): 527 von 672 (78 %).
 
 ## Zusammenfassung
 
 | Paket | Testdateien | Testfälle | grün | rot (Baseline) | übersprungen | mit Beschreibung |
 | --- | ---: | ---: | ---: | ---: | ---: | ---: |
-| `sn_basis` | 40 | 410 | 410 | 0 | 0 | 410 von 410 (100 %) |
+| `sn_basis` | 41 | 420 | 420 | 0 | 0 | 420 von 420 (100 %) |
 | `sn_verfahrensgebiet` | 12 | 208 | 166 | 34 | 8 | 106 von 208 (51 %) |
 | `sn_plan41` | 5 | 44 | 43 | 1 | 0 | 1 von 44 (2 %) |
-| **Summe** | **57** | **662** | **619** | **35** | **8** | **517 von 662 (78 %)** |
+| **Summe** | **58** | **672** | **629** | **35** | **8** | **527 von 672 (78 %)** |
 
 ### Legende
 
@@ -31,7 +31,7 @@ Mit Beschreibung (Docstring): 517 von 662 (78 %).
 
 ## Paket `sn_basis`
 
-Plattform-Plugin, Ordner `Plugin_SN_Basis` – 40 Testdateien mit 410 Testfällen (410 grün, 0 rot, 0 übersprungen).
+Plattform-Plugin, Ordner `Plugin_SN_Basis` – 41 Testdateien mit 420 Testfällen (420 grün, 0 rot, 0 übersprungen).
 
 ### `Plugin_SN_Basis/tests/test_base_dockwidget.py`
 
@@ -592,6 +592,29 @@ Testgruppen:
 | `IsCaseSensitiveFsTests.test_macos_ist_nicht_case_sensitiv` | Prüft, dass macOS als nicht case-sensitives Dateisystem gilt. | grün |
 | `IsCaseSensitiveFsTests.test_linux_ist_case_sensitiv` | Prüft, dass Linux als case-sensitives Dateisystem gilt. | grün |
 
+### `Plugin_SN_Basis/tests/test_print_kartenrand.py`
+
+Worum es in der Datei geht: Tests für modules/print_kartenrand.py – Anordnung des Kartenrands neben der Karte (Basis #93).
+
+Testgruppen:
+
+- `TestBerechneAnordnung` (5 Testfälle): — (Docstring fehlt)
+- `TestOrdneKartenrandAn` (3 Testfälle): — (Docstring fehlt)
+- `TestAnbindungPrintLayout` (2 Testfälle): — (Docstring fehlt)
+
+| Testfall | prüft | Status |
+| --- | --- | --- |
+| `TestBerechneAnordnung.test_passt_einspaltig_nichts_aendert_sich` | Prüft, dass bei genug Platz neben der Karte einspaltig angeordnet wird und Seite und Kartenschild bleiben. | grün |
+| `TestBerechneAnordnung.test_mehr_spalten_und_breiterer_rand` | Prüft, dass bei zu hohen Legenden die kleinste passende Spaltenzahl gewählt und der Kartenrand dafür verbreitert wird. | grün |
+| `TestBerechneAnordnung.test_seite_wird_hoeher_wenn_auch_drei_spalten_nicht_reichen` | Prüft, dass die Seite höher wird und Quellenangabe und Kartenschild nach unten rutschen, wenn auch drei Spalten nicht reichen. | grün |
+| `TestBerechneAnordnung.test_seite_wird_nie_kleiner` | Prüft, dass Seitenbreite und -höhe nie unter die ursprüngliche Seitengröße fallen. | grün |
+| `TestBerechneAnordnung.test_ohne_legenden_nur_kartenschild` | Prüft, dass ohne Legenden nur Quellenangabe und Kartenschild zählen und die Seite bei zu niedriger Karte höher wird. | grün |
+| `TestOrdneKartenrandAn.test_seite_hoeher_und_kartenschild_verschoben` | Prüft, dass bei zu niedriger Karte die Legende dreispaltig wird, die Seite wächst und Quellenangabe und Kartenschild um denselben Betrag nach unten rutschen. | grün |
+| `TestOrdneKartenrandAn.test_passt_nichts_wird_verschoben` | Prüft, dass bei ausreichend hoher Karte weder Seite noch Kartenschild verändert werden. | grün |
+| `TestOrdneKartenrandAn.test_ohne_karte_keine_anordnung` | Prüft, dass ein Layout ohne Hauptkarte unverändert bleibt. | grün |
+| `TestAnbindungPrintLayout.test_vorlage_ordnet_kartenrand_an` | Prüft, dass PrintLayout beim Anlegen einer Vorlage den Kartenrand anordnen lässt. | grün |
+| `TestAnbindungPrintLayout.test_fehler_bei_der_anordnung_verhindert_die_vorlage_nicht` | Prüft, dass ein Fehler bei der Anordnung nur als Warnung gemeldet wird und keine Ausnahme durchreicht. | grün |
+
 ### `Plugin_SN_Basis/tests/test_print_layout.py`
 
 Worum es in der Datei geht: — (Docstring fehlt)
@@ -1426,7 +1449,7 @@ Arbeitsliste: Diese Testfälle haben keinen Docstring; was sie fachlich prüfen,
 aus dem Quelltext erschließen. Jeder Eintrag braucht eine einzeilige Beschreibung im Testfall,
 dann verschwindet er hier von selbst.
 
-### `sn_basis` – 0 von 410 Testfällen ohne Beschreibung
+### `sn_basis` – 0 von 420 Testfällen ohne Beschreibung
 
 Keine Lücken.
 
diff --git a/docs/wissen/fallstricke.md b/docs/wissen/fallstricke.md
index 83bc28f..897304b 100644
--- a/docs/wissen/fallstricke.md
+++ b/docs/wissen/fallstricke.md
@@ -84,6 +84,10 @@ Kurz, konkret, mit Datum und Quelle. Neue Einträge oben in der passenden Rubrik
   berechnen; für mehrere Spalten zusätzlich `setSplitLayer(True)`, sonst bleibt ein Layer in einer Spalte.
   Eine Legende mit `setLegendFilterByMapEnabled(True)` blendet Layer aus, die nicht in der Karte liegen, und ihre
   Höhe steht erst nach dem Rendern fest. (02.10.2026, Spike Basis #88)
+  Auch `QgsLegendRenderer.minimumSize` liefert vor dem ersten Zeichnen die **ungefilterte** Höhe (Beispiel: 344 statt
+  177 mm). Verlässlich vermessen: Legende einmal mit geringer Auflösung zeichnen
+  (`QgsLayoutExporter(layout).renderRegionToImage(legende.sceneBoundingRect(), QSize(), 25)`), danach wirken
+  Filter und `adjustBoxSize`. (02.10.2026, Basis #93)
 - **Projektvariablen-Schlüssel ohne `sn_` übergeben.** `set_variable("sn_abdeckungslayer", ...)` erzeugt `sn_sn_abdeckungslayer` (Altlast in Druckmodulen; funktioniert nur, weil Lesen und Schreiben denselben Fehler machen).
 - **Zwei Schreibweisen für den Verfahrensgebiet-Layer:** `verfahrensgebiet_layer` (Manager, Fachplugins) und `verfahrensgebietslayer` (`print_logic.py`). Bis zur Bereinigung nicht auf Gleichheit vertrauen.
 - **Layer werden über Anzeigenamen gefunden** (`BROR_LAYER_NAME` usw.). Umbenennungen in der UI brechen Abläufe.