Files
Projektwissen/docs/architektur/modulkarte.md
T
DanielandClaude Opus 5.5 67f11e0da7 Basemap-Themen (Basis #100) dokumentiert
Schnittstellen (Thema/Stil, Layer-Eigenschaften, neue Wrapper-Funktionen),
Fallstricke (Relief mit mehreren Quellen, Prüfwert, P10 Vektor),
Glossar (Thema, Stil), Modulkarte, Testkatalog und STATUS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 21:27:36 +02:00

151 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Modulkarte
Lebende Referenz: **welche Datei tut was und wie groß ist sie**. Zweck: Agenten und Entwickler lesen gezielt statt ganze
Dateien zu laden. Zeilenzahlen Stand 02.09.2026 (`unstable`). Bei Änderungen an Modulzuschnitt bitte mitpflegen.
Legende: ⚠ = über 600 Zeilen, nie komplett laden, per `grep -n "def "` navigieren.
## sn_basis (Repository `Plugin_SN_Basis`) – Plattform
### Einstieg und UI-Rahmen
| Datei | Zeilen | Zweck |
|---|---:|---|
| `__init__.py` | 20 | `classFactory` → `BasisPlugin` |
| `main.py` | 64 | `BasisPlugin`: baut `Navigation`, startet Verfahrensgebiet-Listener, ruft `initGui()` aller `sn_*`-Plugins nach, räumt beim Unload auf |
| `ui/navigation.py` | 127 | Menü und Toolbar „LNO Sachsen“; `add_action(text, callback, tooltip, priority)`, `finalize_menu_and_toolbar()`, `set_active_plugin()`. Enthält noch Debug-`print` und eine `TEST ACTION` |
| `ui/dockmanager.py` | 86 | `DockManager.show(dock)`: entfernt alle anderen `sn_dock_*`-Docks, zeigt das neue rechts an |
| `ui/base_dockwidget.py` | 126 | `BaseDockWidget`: Titel „LNO Sachsen \| <Untertitel>“, Tabs aus Klassenattribut `tabs`, ruft `cleanup()` der Tabs beim Schließen, setzt Toolbar-Action zurück |
| `ui/tabs/settings_tab.py` | 158 | Tab „Projekteigenschaften“: Benutzer- und Projektfelder → Projektvariablen (`SettingsLogic`) |
| `ui/tabs/print_tab.py` ⚠ | 730 | Tab „Druck“: Druckbereich, Maßstab, Format, Themen, Legende, Atlas, Basemap-Bereich; nutzt `print_logic` |
| `ui/widgets/basemap_bereich.py` | 433 | Einklappbarer Bereich „Basemap“ im Druck-Tab: Basemap hinzufügen und Thema wechseln (#100), Auswertebereich, Legende aktualisieren, Stilvorlagen |
### functions/ – Wrapper-Schicht (Qt/QGIS/OS mit Mock-Fallback)
| Datei | Zeilen | Zweck |
|---|---:|---|
| `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 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` | 271 | `iface`-Zugriffe: Hauptfenster, Docks, Menüs, Toolbars, Layoutdesigner, aktiver Layer (`get_active_layer`); Mock-`iface` |
| `functions/dialog_wrapper.py` | 570 | Dialoge: `ask_yes_no`, `show_info_dialog`, `ask_text`, Überschreiben/Anhängen/Abbrechen, `ask_auswahl` (frei benannte Knöpfe), `ProgressDialog`/`create_progress_dialog`, `ask_mehrfachauswahl` (Liste mit Häkchen) |
| `functions/message_wrapper.py` | 85 | MessageBar: `info`, `warning`, `error`, `success`, `push_message` |
| `functions/variable_wrapper.py` | 120 | `get_variable(key, scope)`, `set_variable(...)` mit Präfix `sn_`; Mock-Speicher |
| `functions/settings_logic.py` | 50 | `SettingsLogic.VARIABLEN`: Liste der gespeicherten Projektvariablen, `load()/save()` |
| `functions/verfahrensgebiet_manager.py` | 217 | Zentrale Verfolgung des Verfahrensgebiet-Layers über Projektsignale; `get/set_verfahrensgebiet_layer_id`, `setup_/teardown_verfahrensgebiet_listener` |
| `functions/ly_*_wrapper.py` | 32–98 | Layer-Helfer: Existenz, Geometrie/Featurezahl, Metadaten (Typ, CRS, Felder, Quelle), Stil (`apply_style`), Sichtbarkeit |
| `functions/os_wrapper.py` | 102 | Pfade, Home, Groß-/Kleinschreibung des Dateisystems |
| `functions/sys_wrapper.py` | 106 | `get_plugin_root`, `join_path`, `file_exists`, `read_text`, `add_to_sys_path`, `getattr_safe` |
| `functions/landkreise.py` | 48 | Sächsische Landkreise aus `data/landkreise.json` (`LANDKREISE`, `ALLE_LANDKREISE`) |
| `functions/laenderkennung.py` | 52 | ALKIS-Länderkennung je Aufrufer-Präfix |
| `functions/text_wrapper.py` | 25 | `sanitize_bezeichner(text, ersatz="_")`: Freitext → Layer-/Dateiname, Umlaute/ß/_/- bleiben erhalten |
### modules/ – Prüfen, Laden, Schreiben, Drucken
| Datei | Zeilen | Zweck |
|---|---:|---|
| `modules/pruef_ergebnis.py` | 196 | `pruef_ergebnis(ok, meldung, aktion, kontext)` und `PruefAktion`-Literal (Fehler-/Entscheidungscodes) |
| `modules/Pruefmanager.py` | 295 | Entscheidungsinstanz: `verarbeite(ergebnis)` fragt Nutzer oder entscheidet still (`ui_modus != "qgis"`); `report_error`, `frage_ja_nein`, `frage_text` |
| `modules/Dateipruefer.py` | 267 | Prüft Dateipfade/GeoPackages (existiert, erzeugen, überschreiben, anhängen) |
| `modules/layerpruefer.py` | 183 | Prüft QGIS-Layer (vorhanden, Geometrietyp, CRS, Felder, editierbar) |
| `modules/linkpruefer.py` | 136 | Prüft URLs/lokale Links (Erreichbarkeit) |
| `modules/stilpruefer.py` | 82 | Prüft QML-Stildateien |
| `modules/Datenbankpruefer.py` | 40 | Prüft SQLite/GeoPackage-Datenbanken |
| `modules/DataGrabber.py` | 363 | Klassifiziert Quelle (Excel, GeoPackage, Dienst) und liefert normalisierte Zeilen; Excel-Pfad nutzt **Lazy-Import** `sn_plan41.modules.listenauswerter` |
| `modules/excel_importer.py` | 92 | Excel lesen (`openpyxl`, harte Abhängigkeit) |
| `modules/Datenabruf.py` ⚠ | 636 | `Datenabruf.datenabruf(...)`: WFS, ArcGIS REST, OGR laden; Raumfilter Verfahrensgebiet/Puffer/ohne |
| `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 127 | `PrintLayout`: Layoutaufbau für § 38 / § 41 (Karte, Legende, Gitter, Schriftfeld) |
| `modules/print_kartenrand.py` | 284 | Kartenrand (Legenden, Quellenangabe, Kartenschild) überlappungsfrei anordnen: 1–3 Legendenspalten, Rand breiter, Seite ggf. höher (#93); Legenden-Mindestbreite 180 mm samt Listener für das Neuladen (#96) |
| `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 |
| `modules/basemap_legende_layout.py` | 471 | Legendensymbole aus Projektlayer-Styles zusammensetzen (weiße Flächen mit Legendenrand, #92), leere Hilfslayer, Legendenelement „Legende Basemap“ schreiben und platzieren |
| `modules/basemap_katalog.py` | 418 | Erzeugt/aktualisiert `data/basemap_legende.json` aus der basemap.de-Style-JSON (nur Standardbibliothek, eigenständig aufrufbar) |
| `modules/basemap_stilkorrektur.py` | 99 | Darstellungsfehler des Basemap-Layers korrigieren: Punktlinien mit Strichlänge 0 sichtbar machen (#90) |
| `modules/basemap_stilvorlagen.py` | 188 | Lokale Stilvorlagen des Basemap-Layers (QML + JSON im QGIS-Profil, mit Thema), Standard in `QSettings` |
| `modules/basemap_themen.py` | 245 | Themen des Basemap-Layers (Farbe, Grau): Layer anlegen, an der Quell-URL erkennen, Thema wechseln, Prüfwert der Darstellung für ungespeicherte Änderungen (#100) |
### Sonstiges
| Pfad | Zweck |
|---|---|
| `tests/` | 13 Testdateien, `unittest`, Mock-Modus; `run_tests.py` (farbiger Runner), `test_qgis.bat` (Coverage in OSGeo4W) |
| `styles/` | QML-Stile (Verfahrensgebiet, LSG, Denkmalschutz, Flurstücksbeschriftung) |
| `data/landkreise.json` | Landkreise mit Kennzahl |
| `data/basemap_legende.json` | Legendenkatalog basemap.de: Style-ID → Legendeneintrag (190 Einträge), erzeugt mit `basemap_katalog.py`, fachlich nachbearbeitet |
| `assets/plan-qgis340ExitCrashFix.prompt.md` | KI-Planungsnotiz zum Exit-Crash (historisch) |
| `.gitea/workflows/release.yaml`, `.gitea/templates/metadata.template` | Release-Auslöser, Vorlage für `metadata.txt` |
## sn_verfahrensgebiet (Repository `Plugin_SN_Verfahrensgebiet`) – Fachplugin
| Datei | Zeilen | Zweck |
|---|---:|---|
| `main.py` | 80 | `Verfahrensgebiet`: registriert Action (Priorität 10), erzeugt `DockWidget` mit `Pruefmanager` und `DataGrabber` |
| `ui/dockwidget.py` | 60 | Tabs `WorkingTab`, `PrintTab`, `SettingsTab`; injiziert Services per `set_services()` |
| `ui/tabs/working_tab.py` ⚠ | 873 | Tab „Bearbeitung“: Buttons und Handler für ALKIS/Shape laden, Gemarkungen, Flurstücke, Grenzpunkte, Beteiligung, Statistik; hält viel Ablauflogik |
| `functions/verfahrensgebiet_alkis.py` | 359 | WFS-Suche `BauRaumOderBodenordnungsrecht` per Verfahrensnummer/Landkreis, `LoadStatus` |
| `functions/verfahrensgebiet_alkis_komplett.py` ⚠ | 661 | Vollständiger Ladeablauf aus ALKIS: BROR → Gemarkungen → Flurstücke → Flächenvergleich → Detailprüfung |
| `functions/verfahrensgebiet_shape_komplett.py` ⚠ | 978 | Ladeablauf aus Shape/ZIP (Mehrfachauswahl, `FBSchl`-Klassifikation, Abgleich mit BROR) – siehe `docs/aus_shape_laden_technisch.md` im Repo |
| `functions/verfahrensgebiet_dialoge.py` | 300 | Dialoge: BROR-Kombinationen, Landkreis-Objekte, Landkreisauswahl |
| `functions/verfahrensgebiet_edit_service.py` | 359 | Verfahrensgebiet aus Flurstücksauswahl bilden, ergänzen, entfernen, ersetzen |
| `functions/gemarkung_alkis.py` | 229 | Gemarkungen aus vereinfachtem ALKIS-WFS |
| `functions/flurstueck_alkis.py` | 259 | Flurstücke je Gemarkung aus ALKIS-SF-WFS (BBOX, Batches) |
| `functions/grenzpunkt_alkis.py` ⚠ | 1 674 | Grenzpunkte/`PunktortTA` gemarkungsweise, GML-Parsing, URL-sichere Batches |
| `functions/knickpunkt_pruefung.py` ⚠ | 810 | Knickpunktbasierte BROR-Prüfung, Ergebnislayer mit Kategorien |
| `functions/umringspruefung.py` | 312 | Umringsprüfung (Variante 1) |
| `functions/umringstatistik_grenzpunkte.py` | 374 | Statistik Grenzpunkte am Umring |
| `functions/beteiligung_pruefung.py` | 453 | Abgleich BI-Server-CSV mit ALKIS-Flurstücken |
| `tests/` | 12 Dateien | Mock-Modus, aktuell 157/201 grün (Baseline) |
| `docs/` | 3 Dateien | Ablaufdiagramme (Mermaid) für ALKIS- und Shape-Laden |
| `styles/` | 6 QML | BROR, Gemarkungen, Beteiligung, Verfahrensgebiet |
## sn_plan41 (Repository `Plugin_SN_Plan41`) – Fachplugin
| Datei | Zeilen | Zweck |
|---|---:|---|
| `main.py` | 71 | `Plan41`: Action mit Priorität 20, Dock mit `Pruefmanager`/`DataGrabber` |
| `ui/dockwidget.py` | 65 | Tabs `TabA` (Daten), `TabB` (Beispiel), `PrintTab`, `SettingsTab` |
| `ui/tab_a_ui.py` ⚠ | 633 | UI von Tab A: Verfahrens-GeoPackage, Linkliste, Raumfilter, VLN-API-Bereich |
| `ui/tab_a_logic.py` ⚠ | 1 239 | Fachlogik Tab A: Prüf-Pipeline (Datei, Linkliste, Stil, Layer), Abruf über `DataGrabber`/`Datenabruf`, Schreiben, Protokoll; `_SilentPruefmanagerProxy` |
| `ui/tabs/tab_b.py` | 27 | Beispiel-Tab ohne Funktion |
| `modules/listenauswerter.py` | 142 | Validiert Linklistenzeilen (Schema `ident, gruppe, kartenebene, inhalt, link, provider, stildatei`) – wird von `sn_basis.DataGrabber` lazy importiert |
| `modules/vln_api_client.py` | 249 | HTTP-Client VLN-Karten-API v2 (Login, `X-API-Key`, Verfahren, Plan41-Datensatz, Upload) |
| `modules/vln_api_logic.py` | 379 | Ablauflogik der API-Integration in Tab A |
| `modules/vln_layer_manager.py` | 178 | GeoJSON ↔ Memory-Layer nach Geometriefamilie (Punkt/Linie/Fläche), EPSG:25833 |
| `assets/` | 33 Dateien | `Linkliste.xlsx` (44 Dienste) und QML-Stile |
| `doc/Datenbank_ERD.md` | 57 | Ziel-Datenmodell (Maßnahmen, Konten, Ausbauarten, Akteure) – Entwurf, nicht implementiert |
| `tests/` | 5 Dateien | 43/44 grün (Baseline) |
## sn_widmung (Repository `Plugin_SN_Widmung`) – Gerüst
`main.py` (Priorität 30), `ui/dockwidget.py`, `ui/tabs/tab_a.py`, `tab_b.py`: Registrierung funktioniert, Tabs enthalten nur Platzhalter. Keine Tests.
Dient als **minimales Muster** für ein neues Fachplugin (Skill `sn-neues-fachplugin`).
## Platzhalter und Infrastruktur
| Repository | Inhalt |
|---|---|
| `Plugin_SN_FLT`, `Plugin_SN_Topografie`, `Plugin_SN_Template` | nur Release-Workflow, Metadata-Vorlage (teils noch `Plugin_SN_Neu`), leere README |
| `Plugin_Test_Action` | Minimalplugin zum Testen der Release-Pipeline |
| `Repository` | `plugins.xml` (stable, leer), `plugins-testing.xml`, `plugins-unstable.xml`; Branches `hidden/workflows` (zentrale Release-Orchestrierung) und `hidden/templates` |
| `Linkliste` | `linkliste.csv` → Gitea Action erzeugt XML/JSON/YAML |
| `Defaults` | Beispiel-Verfahrensdaten (JSON) und `styles/verfahrensgebiet.qml`; nicht vom Code referenziert |
## Größte Dateien (Kandidaten für das spätere Refactoring)
| Datei | Zeilen |
|---|---:|
| `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 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 |
| `sn_basis/functions/qt_wrapper.py` | 832 |
| `sn_basis/ui/tabs/print_tab.py` | 730 |