diff --git a/docs/architektur/modulkarte.md b/docs/architektur/modulkarte.md index 855a2e6..7b1f6d1 100644 --- a/docs/architektur/modulkarte.md +++ b/docs/architektur/modulkarte.md @@ -18,7 +18,7 @@ Legende: ⚠ = über 600 Zeilen, nie komplett laden, per `grep -n "def "` navigi | `ui/base_dockwidget.py` | 126 | `BaseDockWidget`: Titel „LNO Sachsen \| “, 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` | 271 | Einklappbarer Bereich „Basemap“ im Druck-Tab: Auswertebereich, Legende aktualisieren, Stilvorlagen | +| `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) @@ -27,8 +27,8 @@ 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 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/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()` | @@ -65,7 +65,8 @@ Legende: ⚠ = über 600 Zeilen, nie komplett laden, per `grep -n "def "` navigi | `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` | 181 | Lokale Stilvorlagen des Basemap-Layers (QML + JSON im QGIS-Profil), Standard in `QSettings` | +| `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 diff --git a/docs/architektur/schnittstellen.md b/docs/architektur/schnittstellen.md index 49e4bd6..5c33dde 100644 --- a/docs/architektur/schnittstellen.md +++ b/docs/architektur/schnittstellen.md @@ -148,9 +148,24 @@ flowchart LR - **Legendenkatalog:** `sn_basis/data/basemap_legende.json` (Style-ID → Eintrag), erzeugt/aktualisiert mit `python modules/basemap_katalog.py`; gehört zur Style-Version `bm_web_col` v2. - **Stilvorlagen:** lokal unter `/sn_basis/basemap_stile/`, Standard in `QSettings` - `sn_basis/basemap_standardstil`. + `sn_basis/basemap_standardstil`. Die Begleit-JSON trägt seit #100 das Feld `thema` (Schlüssel aus + `basemap_themen.THEMEN`; fehlt bei älteren Vorlagen). +- **Thema und Stil (Basis #100):** *Thema* = vom Dienst als Style-JSON gelieferte Darstellung (`farbe` → + `bm_web_col.json`, `grau` → `bm_web_gry.json`); *Stil* = lokale Anpassung (Stilvorlage). Alle Themen nutzen + dieselbe Kachel-URL `…/tiles/v2/bm_web_de_3857/{z}/{x}/{y}.pbf`; das Thema steht im Quellparameter `styleUrl`. + „Schon vorhanden“ heißt: ein Layer mit identischer Kachel-URL (Quellparameter `url`). +- **Layer-Eigenschaften des Basemap-Layers (#100):** `sn_basemap_thema` (Schlüssel des zuletzt geladenen Themas) + und `sn_basemap_pruefwert` (SHA-256 der QML von Symbologie und Beschriftung ohne QGIS-Version, gesetzt nach + Laden eines Themas oder Stils und nach Speichern als Stil). Fehlt der Prüfwert, gilt der Änderungsstand als + unbekannt und vor dem Themenwechsel wird nachgefragt. +- **Themenwechsel:** `basemap_themen.wechsle_thema` stellt die Quelle per `setDataSource` um und lädt + `loadDefaultStyle()`; Layer-ID, Position im Layerbaum und Bezüge in Layouts bleiben. Ziel ist der im Layerbaum + ausgewählte Basemap-Layer, sonst der erste des Projekts. - **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. +- **Neue öffentliche Funktionen (#100):** `dialog_wrapper.ask_auswahl(title, message, optionen, default, abbrechen)` – + Rückfrage mit frei benannten Knöpfen `[(schluessel, beschriftung), …]`, liefert den Schlüssel; Esc/Fehler → + `abbrechen`, Mock-Modus → `default`. `qgisui_wrapper.get_active_layer()` – ausgewählter Layer oder `None`. ## 12. Kartenrand im Standardlayout (Basis #93) diff --git a/docs/status/STATUS.md b/docs/status/STATUS.md index 957e749..7bec6af 100644 --- a/docs/status/STATUS.md +++ b/docs/status/STATUS.md @@ -71,6 +71,11 @@ spätere Phase und beginnt erst, wenn die Test-Baseline grün ist und das Projek (#96: Textumbruch 60 mm, ungleiche Spaltenbreiten, zweizeiliger Basemap-Titel, Mindestbreite 180 mm wie das Kartenschild) auf `Plugin_SN_Basis:bugfix/96-legenden-spaltenbreite`, PR steht aus. +17. **Basemap hinzufügen und Thema wechseln (Basis #100).** Umgesetzt auf + `Plugin_SN_Basis:feature/100-basemap-themen` (Doku: `Projektwissen:docs/100-basemap-themen`), PR steht aus. + Themen Farbe/Grau, Erkennung über Kachel-URL, Prüfwert für ungespeicherte Änderungen. Offen: **QGIS-Test** + (Laden über `styleUrl`, Themenwechsel per `setDataSource`, Stabilität des Prüfwerts). Folge-Issues: #101 + (Import/Export der Stile), P10 Vektor (eigenes Issue, Entwurf liegt vor), Relief. **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 16b3044..bbacea9 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)
-
681Testfälle
-
638grün
+
711Testfälle
+
668grün
35rot (Baseline)
-
79%mit Docstring
-
58Testdateien
+
80%mit Docstring
+
59Testdateien
Verteilung je Paket
-
sn_basis41 Dateien · 429 Testfälle
+
sn_basis42 Dateien · 459 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 · 41 Testdateien · 429 Testfälle

+

Plattform-Plugin · Ordner Plugin_SN_Basis · 42 Testdateien · 459 Testfälle

- @@ -440,7 +440,90 @@ 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
TestStilvorlagen
test_speichern_und_auflisten
Prüft, dass eine gespeicherte Vorlage mit Anzeigenamen, QML-Datei und Begleitdatei aufgelistet wird.grün
TestStilvorlagen
test_mehrere_varianten_alphabetisch
Prüft, dass mehrere Varianten nebeneinander bestehen und alphabetisch nach Anzeigename sortiert werden.grün
TestStilvorlagen
test_leerer_name_oder_fehler_beim_schreiben
Prüft, dass ein leerer Name und ein Schreibfehler von QGIS als ValueError gemeldet werden.grün
TestStilvorlagen
test_laden_setzt_stil_und_zeichnet_neu
Prüft, dass das Laden die QML-Datei der Vorlage in den Layer lädt und neu zeichnen lässt.grün
TestStilvorlagen
test_passung_meldet_fremde_styles
Prüft, dass Style-Namen der Vorlage gemeldet werden, die der Ziel-Layer nicht kennt.grün
TestStilvorlagen
test_standard_setzen_und_beim_loeschen_entfernen
Prüft, dass eine Vorlage als Standard markiert wird und die Markierung beim Löschen der Vorlage entfällt.grün
TestStilvorlagen
test_fehlende_begleitdatei_wird_toleriert
Prüft, dass eine QML-Datei ohne Begleitdatei mit ihrem Dateinamen aufgelistet wird.grün
TestStilvorlagen
test_ohne_ordner_leere_liste
Prüft, dass ohne angelegten Vorlagenordner eine leere Liste zurückkommt.grün

— (Docstring fehlt)

Keine Testfälle: Die Datei enthält keine unittest.TestCase-Klasse – sie ist eine reine Hilfsdatei, die beim Testlauf nur importiert wird.

— (Docstring fehlt)

TestDataGrabber 8
flowchart TD
+  classDef skip fill:#e6e6ee,stroke:#6f7285,stroke-width:1px,color:#2b2d38;
TestfallprüftStatus
TestStilvorlagen
test_speichern_und_auflisten
Prüft, dass eine gespeicherte Vorlage mit Anzeigenamen, QML-Datei und Begleitdatei aufgelistet wird.grün
TestStilvorlagen
test_mehrere_varianten_alphabetisch
Prüft, dass mehrere Varianten nebeneinander bestehen und alphabetisch nach Anzeigename sortiert werden.grün
TestStilvorlagen
test_leerer_name_oder_fehler_beim_schreiben
Prüft, dass ein leerer Name und ein Schreibfehler von QGIS als ValueError gemeldet werden.grün
TestStilvorlagen
test_laden_setzt_stil_und_zeichnet_neu
Prüft, dass das Laden die QML-Datei der Vorlage in den Layer lädt und neu zeichnen lässt.grün
TestStilvorlagen
test_passung_meldet_fremde_styles
Prüft, dass Style-Namen der Vorlage gemeldet werden, die der Ziel-Layer nicht kennt.grün
TestStilvorlagen
test_standard_setzen_und_beim_loeschen_entfernen
Prüft, dass eine Vorlage als Standard markiert wird und die Markierung beim Löschen der Vorlage entfällt.grün
TestStilvorlagen
test_fehlende_begleitdatei_wird_toleriert
Prüft, dass eine QML-Datei ohne Begleitdatei mit ihrem Dateinamen aufgelistet wird.grün
TestStilvorlagen
test_ohne_ordner_leere_liste
Prüft, dass ohne angelegten Vorlagenordner eine leere Liste zurückkommt.grün

Tests für modules/basemap_themen.py und den Abschnitt „Basemap-Layer“ im Basemap-Bereich (Basis #100):

TestQuelleUndThema 4TestPruefwert 3TestLayerUndThemenwechsel 7TestStilvorlageMitThema 1TestAuswahlDialog 1TestBasemapHinzufuegen 5TestThemaWechseln 8TestZielLayer 1
flowchart TD
+  root(["test_basemap_themen.py"])
+  class root rootnode
+  root --> g1["TestQuelleUndThema (4)"]
+  class g1 groupnode
+  g1 --> t1("quelle_enthaelt_kachel_url_und_style_des_themas")
+  g1 --> t2("unbekannte_style_json_ergibt_kein_thema")
+  g1 --> t3("unbekannter_schluessel_faellt_auf_farbe_zurueck")
+  g1 --> t4("vorhandener_layer_wird_an_der_quell_url_erkannt")
+  root --> g2["TestPruefwert (3)"]
+  class g2 groupnode
+  g2 --> t5("gleiche_darstellung_gleicher_pruefwert_auch_bei_anderer_qgis_version")
+  g2 --> t6("ohne_ausgabe_der_darstellung_kein_pruefwert")
+  g2 --> t7("aenderungsstand_unbekannt_unveraendert_geaendert")
+  root --> g3["TestLayerUndThemenwechsel (7)"]
+  class g3 groupnode
+  g3 --> t8("neuer_layer_hat_thema_namen_und_gemerkten_stand")
+  g3 --> t9("ungueltiger_layer_oder_fehlender_themenstil_meldet_fehler")
+  g3 --> t10("ohne_vektorkacheln_kein_layer")
+  g3 --> t11("layer_kommt_ganz_unten_in_den_layerbaum")
+  g3 --> t12("themenwechsel_stellt_quelle_um_und_merkt_neuen_stand")
+  g3 --> t13("themenwechsel_behaelt_eigenen_layernamen")
+  g3 --> t14("themenwechsel_ohne_umstellbare_quelle_meldet_fehler")
+  root --> g4["TestStilvorlageMitThema (1)"]
+  class g4 groupnode
+  g4 --> t15("stilvorlage_vermerkt_das_thema")
+  root --> g5["TestAuswahlDialog (1)"]
+  class g5 groupnode
+  g5 --> t16("mock_modus_liefert_vorbelegung")
+  root --> g6["TestBasemapHinzufuegen (5)"]
+  class g6 groupnode
+  g6 --> t17("ohne_vorhandenen_layer_wird_ohne_rueckfrage_hinzugefuegt")
+  g6 --> t18("vorhandener_layer_wird_in_der_rueckfrage_genannt_abbrechen")
+  g6 --> t19("zusaetzlich_laden_fuegt_zweiten_layer_hinzu")
+  g6 --> t20("ersetzen_laedt_vorhandenen_layer_im_gewaehlten_thema")
+  g6 --> t21("fehler_beim_anlegen_wird_gemeldet")
+  root --> g7["TestThemaWechseln (8)"]
+  class g7 groupnode
+  g7 --> t22("unveraenderter_layer_wechselt_ohne_rueckfrage")
+  g7 --> t23("gleiches_thema_aendert_nichts")
+  g7 --> t24("geaenderte_darstellung_abbrechen_behaelt_thema")
+  g7 --> t25("geaenderte_darstellung_verwerfen_wechselt")
+  g7 --> t26("als_stil_speichern_sichert_vor_dem_wechsel")
+  g7 --> t27("abgebrochenes_speichern_verhindert_den_wechsel")
+  g7 --> t28("unbekannter_stand_fragt_nach")
+  g7 --> t29("ohne_basemap_layer_nur_vorauswahl")
+  root --> g8["TestZielLayer (1)"]
+  class g8 groupnode
+  g8 --> t30("ausgewaehlter_basemap_layer_hat_vorrang")
+  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
+  class t11 ok
+  class t12 ok
+  class t13 ok
+  class t14 ok
+  class t15 ok
+  class t16 ok
+  class t17 ok
+  class t18 ok
+  class t19 ok
+  class t20 ok
+  class t21 ok
+  class t22 ok
+  class t23 ok
+  class t24 ok
+  class t25 ok
+  class t26 ok
+  class t27 ok
+  class t28 ok
+  class t29 ok
+  class t30 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
TestQuelleUndThema
test_quelle_enthaelt_kachel_url_und_style_des_themas
Prüft, dass die Layerquelle eines Themas die gemeinsame Kachel-URL und die Style-JSON des Themas enthält.grün
TestQuelleUndThema
test_unbekannte_style_json_ergibt_kein_thema
Prüft, dass ein Layer mit fremder oder fehlender Style-JSON keinem Thema zugeordnet wird.grün
TestQuelleUndThema
test_unbekannter_schluessel_faellt_auf_farbe_zurueck
Prüft, dass ein unbekannter Themenschlüssel auf das Standardthema „Farbe“ zurückfällt.grün
TestQuelleUndThema
test_vorhandener_layer_wird_an_der_quell_url_erkannt
Prüft, dass ein vorhandener Basemap-Layer an der Kachel-URL erkannt wird – unabhängig von Name, Thema und URL-Kodierung.grün
TestPruefwert
test_gleiche_darstellung_gleicher_pruefwert_auch_bei_anderer_qgis_version
Prüft, dass dieselbe Darstellung denselben Prüfwert ergibt, auch wenn die QGIS-Version in der QML abweicht.grün
TestPruefwert
test_ohne_ausgabe_der_darstellung_kein_pruefwert
Prüft, dass kein Prüfwert entsteht, wenn der Layer seine Darstellung nicht ausgeben kann.grün
TestPruefwert
test_aenderungsstand_unbekannt_unveraendert_geaendert
Prüft, dass der Änderungsstand ohne gemerkten Prüfwert „unbekannt“ ist, nach dem Merken „unverändert“ und nach einer Änderung „geändert“.grün
TestLayerUndThemenwechsel
test_neuer_layer_hat_thema_namen_und_gemerkten_stand
Prüft, dass ein neuer Basemap-Layer im gewählten Thema entsteht, den Themenstil lädt und als unverändert gilt.grün
TestLayerUndThemenwechsel
test_ungueltiger_layer_oder_fehlender_themenstil_meldet_fehler
Prüft, dass ein ungültiger Layer oder ein nicht ladbarer Themenstil als ValueError gemeldet wird.grün
TestLayerUndThemenwechsel
test_ohne_vektorkacheln_kein_layer
Prüft, dass ohne Vektorkachel-Unterstützung (Mock-Modus) kein Layer erzeugt, sondern ein Fehler gemeldet wird.grün
TestLayerUndThemenwechsel
test_layer_kommt_ganz_unten_in_den_layerbaum
Prüft, dass der Basemap-Layer ohne automatische Einordnung ins Projekt kommt und unten an den Layerbaum angehängt wird.grün
TestLayerUndThemenwechsel
test_themenwechsel_stellt_quelle_um_und_merkt_neuen_stand
Prüft, dass der Themenwechsel die Style-JSON der Quelle umstellt, den Themenstil lädt, den automatischen Namen anpasst und den neuen Stand merkt.grün
TestLayerUndThemenwechsel
test_themenwechsel_behaelt_eigenen_layernamen
Prüft, dass ein vom Nutzer vergebener Layername beim Themenwechsel erhalten bleibt.grün
TestLayerUndThemenwechsel
test_themenwechsel_ohne_umstellbare_quelle_meldet_fehler
Prüft, dass ein Layer ohne setDataSource den Themenwechsel mit einem ValueError ablehnt.grün
TestStilvorlageMitThema
test_stilvorlage_vermerkt_das_thema
Prüft, dass eine gespeicherte Stilvorlage das Thema des Layers in ihrer Begleitdatei und in der Liste vermerkt.grün
TestAuswahlDialog
test_mock_modus_liefert_vorbelegung
Prüft, dass die Rückfrage mit frei benannten Knöpfen im Mock-Modus den vorbelegten Schlüssel liefert.grün
TestBasemapHinzufuegen
test_ohne_vorhandenen_layer_wird_ohne_rueckfrage_hinzugefuegt
Prüft, dass ohne Basemap-Layer gleicher Quelle sofort ein Layer im gewählten Thema hinzugefügt wird.grün
TestBasemapHinzufuegen
test_vorhandener_layer_wird_in_der_rueckfrage_genannt_abbrechen
Prüft, dass ein vorhandener Layer gleicher Quelle in der Rückfrage genannt wird und „Abbrechen“ nichts verändert.grün
TestBasemapHinzufuegen
test_zusaetzlich_laden_fuegt_zweiten_layer_hinzu
Prüft, dass „Zusätzlich laden“ einen weiteren Basemap-Layer neben dem vorhandenen hinzufügt.grün
TestBasemapHinzufuegen
test_ersetzen_laedt_vorhandenen_layer_im_gewaehlten_thema
Prüft, dass „Ersetzen“ keinen neuen Layer anlegt, sondern den vorhandenen im gewählten Thema neu lädt.grün
TestBasemapHinzufuegen
test_fehler_beim_anlegen_wird_gemeldet
Prüft, dass ein nicht erreichbarer Dienst als Warnung gemeldet und kein Layer hinzugefügt wird.grün
TestThemaWechseln
test_unveraenderter_layer_wechselt_ohne_rueckfrage
Prüft, dass ein unveränderter Basemap-Layer ohne Rückfrage auf das gewählte Thema wechselt.grün
TestThemaWechseln
test_gleiches_thema_aendert_nichts
Prüft, dass die Wahl des Themas, das der Layer schon hat, nichts neu lädt.grün
TestThemaWechseln
test_geaenderte_darstellung_abbrechen_behaelt_thema
Prüft, dass bei geänderter Darstellung nachgefragt wird und „Abbrechen“ Thema und Darstellung unverändert lässt.grün
TestThemaWechseln
test_geaenderte_darstellung_verwerfen_wechselt
Prüft, dass „Verwerfen“ die geänderte Darstellung aufgibt und das Thema wechselt.grün
TestThemaWechseln
test_als_stil_speichern_sichert_vor_dem_wechsel
Prüft, dass „Als Stil speichern“ die Darstellung vor dem Themenwechsel als Stilvorlage sichert.grün
TestThemaWechseln
test_abgebrochenes_speichern_verhindert_den_wechsel
Prüft, dass das Thema nicht wechselt, wenn „Als Stil speichern“ gewählt, die Namensabfrage aber abgebrochen wird.grün
TestThemaWechseln
test_unbekannter_stand_fragt_nach
Prüft, dass bei einem Layer ohne gemerkten Prüfwert (vor dieser Funktion geladen) vorsichtshalber nachgefragt wird.grün
TestThemaWechseln
test_ohne_basemap_layer_nur_vorauswahl
Prüft, dass die Themenwahl ohne Basemap-Layer nur als Vorauswahl für „Basemap hinzufügen“ dient und nichts meldet.grün
TestZielLayer
test_ausgewaehlter_basemap_layer_hat_vorrang
Prüft, dass der im Layerbaum ausgewählte Basemap-Layer Ziel des Themenwechsels ist, sonst der erste Basemap-Layer.grün

— (Docstring fehlt)

Keine Testfälle: Die Datei enthält keine unittest.TestCase-Klasse – sie ist eine reine Hilfsdatei, die beim Testlauf nur importiert wird.

— (Docstring fehlt)

TestDataGrabber 8
flowchart TD
   root(["test_datagrabber.py"])
   class root rootnode
   root --> g1["TestDataGrabber (8)"]
diff --git a/docs/tests/testkatalog.md b/docs/tests/testkatalog.md
index defb867..914c237 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, 58 Testdateien, 681 Testfälle – 638 grün, 35 rot (Baseline), 8 übersprungen.
-Mit Beschreibung (Docstring): 536 von 681 (79 %).
+Gesamt: 3 Pakete, 59 Testdateien, 711 Testfälle – 668 grün, 35 rot (Baseline), 8 übersprungen.
+Mit Beschreibung (Docstring): 566 von 711 (80 %).
 
 ## Zusammenfassung
 
 | Paket | Testdateien | Testfälle | grün | rot (Baseline) | übersprungen | mit Beschreibung |
 | --- | ---: | ---: | ---: | ---: | ---: | ---: |
-| `sn_basis` | 41 | 429 | 429 | 0 | 0 | 429 von 429 (100 %) |
+| `sn_basis` | 42 | 459 | 459 | 0 | 0 | 459 von 459 (100 %) |
 | `sn_verfahrensgebiet` | 12 | 208 | 166 | 34 | 8 | 106 von 208 (51 %) |
 | `sn_plan41` | 5 | 44 | 43 | 1 | 0 | 1 von 44 (2 %) |
-| **Summe** | **58** | **681** | **638** | **35** | **8** | **536 von 681 (79 %)** |
+| **Summe** | **59** | **711** | **668** | **35** | **8** | **566 von 711 (80 %)** |
 
 ### Legende
 
@@ -31,7 +31,7 @@ Mit Beschreibung (Docstring): 536 von 681 (79 %).
 
 ## Paket `sn_basis`
 
-Plattform-Plugin, Ordner `Plugin_SN_Basis` – 41 Testdateien mit 429 Testfällen (429 grün, 0 rot, 0 übersprungen).
+Plattform-Plugin, Ordner `Plugin_SN_Basis` – 42 Testdateien mit 459 Testfällen (459 grün, 0 rot, 0 übersprungen).
 
 ### `Plugin_SN_Basis/tests/test_base_dockwidget.py`
 
@@ -235,6 +235,54 @@ Testgruppen:
 | `TestStilvorlagen.test_fehlende_begleitdatei_wird_toleriert` | Prüft, dass eine QML-Datei ohne Begleitdatei mit ihrem Dateinamen aufgelistet wird. | grün |
 | `TestStilvorlagen.test_ohne_ordner_leere_liste` | Prüft, dass ohne angelegten Vorlagenordner eine leere Liste zurückkommt. | grün |
 
+### `Plugin_SN_Basis/tests/test_basemap_themen.py`
+
+Worum es in der Datei geht: Tests für modules/basemap_themen.py und den Abschnitt „Basemap-Layer“ im Basemap-Bereich (Basis #100):
+
+Testgruppen:
+
+- `TestQuelleUndThema` (4 Testfälle): Layerquelle der Themen, Thema eines Layers und Erkennung über die Kachel-URL.
+- `TestPruefwert` (3 Testfälle): Prüfwert der Darstellung und Änderungsstand für ungespeicherte Änderungen.
+- `TestLayerUndThemenwechsel` (7 Testfälle): Basemap-Layer anlegen, in den Layerbaum einfügen und Thema wechseln.
+- `TestStilvorlageMitThema` (1 Testfälle): Stilvorlagen vermerken das Thema des Layers.
+- `TestAuswahlDialog` (1 Testfälle): Rückfrage mit frei benannten Knöpfen.
+- `TestBasemapHinzufuegen` (5 Testfälle): Knopf „Basemap hinzufügen“ mit Rückfrage bei vorhandenem Layer gleicher Quelle.
+- `TestThemaWechseln` (8 Testfälle): Themenauswahl mit Rückfrage bei geänderter oder unbekannter Darstellung.
+- `TestZielLayer` (1 Testfälle): Auswahl des Basemap-Layers, auf den Thema und Stil wirken.
+
+| Testfall | prüft | Status |
+| --- | --- | --- |
+| `TestQuelleUndThema.test_quelle_enthaelt_kachel_url_und_style_des_themas` | Prüft, dass die Layerquelle eines Themas die gemeinsame Kachel-URL und die Style-JSON des Themas enthält. | grün |
+| `TestQuelleUndThema.test_unbekannte_style_json_ergibt_kein_thema` | Prüft, dass ein Layer mit fremder oder fehlender Style-JSON keinem Thema zugeordnet wird. | grün |
+| `TestQuelleUndThema.test_unbekannter_schluessel_faellt_auf_farbe_zurueck` | Prüft, dass ein unbekannter Themenschlüssel auf das Standardthema „Farbe“ zurückfällt. | grün |
+| `TestQuelleUndThema.test_vorhandener_layer_wird_an_der_quell_url_erkannt` | Prüft, dass ein vorhandener Basemap-Layer an der Kachel-URL erkannt wird – unabhängig von Name, Thema und URL-Kodierung. | grün |
+| `TestPruefwert.test_gleiche_darstellung_gleicher_pruefwert_auch_bei_anderer_qgis_version` | Prüft, dass dieselbe Darstellung denselben Prüfwert ergibt, auch wenn die QGIS-Version in der QML abweicht. | grün |
+| `TestPruefwert.test_ohne_ausgabe_der_darstellung_kein_pruefwert` | Prüft, dass kein Prüfwert entsteht, wenn der Layer seine Darstellung nicht ausgeben kann. | grün |
+| `TestPruefwert.test_aenderungsstand_unbekannt_unveraendert_geaendert` | Prüft, dass der Änderungsstand ohne gemerkten Prüfwert „unbekannt“ ist, nach dem Merken „unverändert“ und nach einer Änderung „geändert“. | grün |
+| `TestLayerUndThemenwechsel.test_neuer_layer_hat_thema_namen_und_gemerkten_stand` | Prüft, dass ein neuer Basemap-Layer im gewählten Thema entsteht, den Themenstil lädt und als unverändert gilt. | grün |
+| `TestLayerUndThemenwechsel.test_ungueltiger_layer_oder_fehlender_themenstil_meldet_fehler` | Prüft, dass ein ungültiger Layer oder ein nicht ladbarer Themenstil als ValueError gemeldet wird. | grün |
+| `TestLayerUndThemenwechsel.test_ohne_vektorkacheln_kein_layer` | Prüft, dass ohne Vektorkachel-Unterstützung (Mock-Modus) kein Layer erzeugt, sondern ein Fehler gemeldet wird. | grün |
+| `TestLayerUndThemenwechsel.test_layer_kommt_ganz_unten_in_den_layerbaum` | Prüft, dass der Basemap-Layer ohne automatische Einordnung ins Projekt kommt und unten an den Layerbaum angehängt wird. | grün |
+| `TestLayerUndThemenwechsel.test_themenwechsel_stellt_quelle_um_und_merkt_neuen_stand` | Prüft, dass der Themenwechsel die Style-JSON der Quelle umstellt, den Themenstil lädt, den automatischen Namen anpasst und den neuen Stand merkt. | grün |
+| `TestLayerUndThemenwechsel.test_themenwechsel_behaelt_eigenen_layernamen` | Prüft, dass ein vom Nutzer vergebener Layername beim Themenwechsel erhalten bleibt. | grün |
+| `TestLayerUndThemenwechsel.test_themenwechsel_ohne_umstellbare_quelle_meldet_fehler` | Prüft, dass ein Layer ohne setDataSource den Themenwechsel mit einem ValueError ablehnt. | grün |
+| `TestStilvorlageMitThema.test_stilvorlage_vermerkt_das_thema` | Prüft, dass eine gespeicherte Stilvorlage das Thema des Layers in ihrer Begleitdatei und in der Liste vermerkt. | grün |
+| `TestAuswahlDialog.test_mock_modus_liefert_vorbelegung` | Prüft, dass die Rückfrage mit frei benannten Knöpfen im Mock-Modus den vorbelegten Schlüssel liefert. | grün |
+| `TestBasemapHinzufuegen.test_ohne_vorhandenen_layer_wird_ohne_rueckfrage_hinzugefuegt` | Prüft, dass ohne Basemap-Layer gleicher Quelle sofort ein Layer im gewählten Thema hinzugefügt wird. | grün |
+| `TestBasemapHinzufuegen.test_vorhandener_layer_wird_in_der_rueckfrage_genannt_abbrechen` | Prüft, dass ein vorhandener Layer gleicher Quelle in der Rückfrage genannt wird und „Abbrechen“ nichts verändert. | grün |
+| `TestBasemapHinzufuegen.test_zusaetzlich_laden_fuegt_zweiten_layer_hinzu` | Prüft, dass „Zusätzlich laden“ einen weiteren Basemap-Layer neben dem vorhandenen hinzufügt. | grün |
+| `TestBasemapHinzufuegen.test_ersetzen_laedt_vorhandenen_layer_im_gewaehlten_thema` | Prüft, dass „Ersetzen“ keinen neuen Layer anlegt, sondern den vorhandenen im gewählten Thema neu lädt. | grün |
+| `TestBasemapHinzufuegen.test_fehler_beim_anlegen_wird_gemeldet` | Prüft, dass ein nicht erreichbarer Dienst als Warnung gemeldet und kein Layer hinzugefügt wird. | grün |
+| `TestThemaWechseln.test_unveraenderter_layer_wechselt_ohne_rueckfrage` | Prüft, dass ein unveränderter Basemap-Layer ohne Rückfrage auf das gewählte Thema wechselt. | grün |
+| `TestThemaWechseln.test_gleiches_thema_aendert_nichts` | Prüft, dass die Wahl des Themas, das der Layer schon hat, nichts neu lädt. | grün |
+| `TestThemaWechseln.test_geaenderte_darstellung_abbrechen_behaelt_thema` | Prüft, dass bei geänderter Darstellung nachgefragt wird und „Abbrechen“ Thema und Darstellung unverändert lässt. | grün |
+| `TestThemaWechseln.test_geaenderte_darstellung_verwerfen_wechselt` | Prüft, dass „Verwerfen“ die geänderte Darstellung aufgibt und das Thema wechselt. | grün |
+| `TestThemaWechseln.test_als_stil_speichern_sichert_vor_dem_wechsel` | Prüft, dass „Als Stil speichern“ die Darstellung vor dem Themenwechsel als Stilvorlage sichert. | grün |
+| `TestThemaWechseln.test_abgebrochenes_speichern_verhindert_den_wechsel` | Prüft, dass das Thema nicht wechselt, wenn „Als Stil speichern“ gewählt, die Namensabfrage aber abgebrochen wird. | grün |
+| `TestThemaWechseln.test_unbekannter_stand_fragt_nach` | Prüft, dass bei einem Layer ohne gemerkten Prüfwert (vor dieser Funktion geladen) vorsichtshalber nachgefragt wird. | grün |
+| `TestThemaWechseln.test_ohne_basemap_layer_nur_vorauswahl` | Prüft, dass die Themenwahl ohne Basemap-Layer nur als Vorauswahl für „Basemap hinzufügen“ dient und nichts meldet. | grün |
+| `TestZielLayer.test_ausgewaehlter_basemap_layer_hat_vorrang` | Prüft, dass der im Layerbaum ausgewählte Basemap-Layer Ziel des Themenwechsels ist, sonst der erste Basemap-Layer. | grün |
+
 ### `Plugin_SN_Basis/tests/test_bootstrap.py`
 
 Worum es in der Datei geht: — (Docstring fehlt)
@@ -1459,7 +1507,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 429 Testfällen ohne Beschreibung
+### `sn_basis` – 0 von 459 Testfällen ohne Beschreibung
 
 Keine Lücken.
 
diff --git a/docs/wissen/fallstricke.md b/docs/wissen/fallstricke.md
index 31bb6ff..2008d3e 100644
--- a/docs/wissen/fallstricke.md
+++ b/docs/wissen/fallstricke.md
@@ -68,6 +68,20 @@ Kurz, konkret, mit Datum und Quelle. Neue Einträge oben in der passenden Rubrik
   Der Legendenkatalog `sn_basis/data/basemap_legende.json` gehört zur Style-Version `bm_web_col` v2; nach einer
   neuen Version `python modules/basemap_katalog.py` laufen lassen und Meldungen prüfen. Eine QML-Stilvorlage des
   Layers ist rund 3,7 MB groß. (02.10.2026)
+- **basemap.de-Themen (Basis #100):** Angeboten werden Farbe (`bm_web_col`), Grau (`bm_web_gry`) und Relief
+  (`bm_web_top`); `bm_web_bin` liegt auf dem Server, steht aber nicht auf basemap.de. Farbe und Grau nutzen nur die
+  Kachelquelle `bm_web_de_3857`. **Relief braucht zusätzlich** die Höhenlinien-Kacheln `bm_web_hl_de_3857` und zwei
+  WMS-Schummerungen – ein einzelner QGIS-Vektorkachel-Layer hat nur eine Kachelquelle, Relief ist deshalb vorerst
+  nicht im Themen-Dropdown. Style-Version der JSONs am 05.10.2026: `basemapde:style-version` 5.1.0.
+- **QGIS kennt kein „Darstellung geändert“-Kennzeichen pro Layer.** Für ungespeicherte Änderungen am Thema wird
+  deshalb ein Prüfwert der QML (Symbologie + Beschriftung, ohne `version`-Attribut) als Layer-Eigenschaft gemerkt
+  und vor dem Themenwechsel verglichen (`basemap_themen.aenderungsstand`). Die Berechnung schreibt die rund 3,7 MB
+  große QML in eine temporäre Datei. Ob dieselbe Darstellung in QGIS stets dieselbe QML ergibt, ist im QGIS-Test zu
+  bestätigen. Auch „Punktlinien korrigieren“ zählt als Änderung. (05.10.2026)
+- **basemap.de P10 Vektor ist kein Kacheldienst.** Es ist ein bundesweites GeoPackage (rund 60 GB, 47 normale
+  Vektorlayer, Varianten col/gry, Beta vom 14.08.2026, optimiert für QGIS 3.44.8). Die Basemap-Werkzeuge in `sn_basis`
+  (Erkennung, `selectByGeometry`, Legendenkatalog nach Style-IDs, Stilvorlagen über `renderer().styles()`) setzen
+  Vektorkacheln voraus und greifen dort nicht. Eigenes Issue. (05.10.2026)
 - **WFS-Beschränkungen der sächsischen ALKIS-Dienste:** POST/GML-Filter werden blockiert, URL-Länge ist begrenzt, serverseitige Feature-Limits. Deshalb arbeiten Flurstücks- und Grenzpunktabrufe mit BBOX, gemarkungsweisen Batches und Nutzerdialogen. Nicht „vereinfachen“, ohne das gegen den Dienst zu testen. Vollständig mit erprobten Anfragen: `docs/wissen/wfs_dienste.md`, Objektarten/Attribute: `docs/wissen/alkis_objektarten.md`. (Verfahrensgebiet, Code)
 - **Zwei Linklisten.** Zentrale `Linkliste/linkliste.csv` (Spalten `id;gruppe;ebene;inhalt;url;provider;stil`) und die vom Plugin genutzte `Plugin_SN_Plan41/assets/Linkliste.xlsx` (`ident, gruppe, kartenebene, inhalt, link, provider, stildatei`) sind nicht verbunden. Änderungen an Diensten in **beiden** nachziehen, bis die Zusammenführung entschieden ist. (09/2026)
 - **ArcGIS-REST-Layer nicht nach Nummer deuten.** Gleiche Layer-URLs werden in der Linkliste und im Alternativansatz unterschiedlich benannt; Bedeutung und Geometrie immer gegen die Dienstmetadaten prüfen. (Vergleich Alternativansatz 09/2026)
diff --git a/docs/wissen/glossar.md b/docs/wissen/glossar.md
index cc41149..ae74472 100644
--- a/docs/wissen/glossar.md
+++ b/docs/wissen/glossar.md
@@ -36,4 +36,7 @@ Flurbereinigungs-Hintergrund. Ergänzen, wenn ein Begriff im Issue erklärt werd
 | **Atlas** | QGIS-Serienkarte über einen Abdeckungslayer (`sn_abdeckungslayer`) |
 | **Kanal** | Release-Kanal: stable, testing, unstable (QGIS-Plugin-Feeds in `Repository`) |
 | **Mock-Modus** | Betrieb der Wrapper ohne QGIS/Qt für Tests |
+| **basemap.de** | Bundesweite Hintergrundkarte der Vermessungsverwaltungen; in `sn_basis` als Vektorkachel-Layer genutzt (Basemap-Legende, Basemap-Bereich im Druck-Tab) |
+| **Thema (Basemap)** | Vom Dienst basemap.de als Style-JSON bereitgestellte Darstellung: Farbe, Grau (Relief vorerst nicht). Nicht verwechseln mit *Stil* und mit QGIS-Kartenthemen |
+| **Stil (Basemap)** | Lokale Anpassung der Darstellung durch den Nutzer, als Stilvorlage im QGIS-Profil gespeichert; vermerkt, zu welchem Thema sie gehört |
 | **AG QGIS** | Arbeitsgruppe QGIS der sächsischen Flurbereinigungsbehörden; Gitea-Organisation `AG_QGIS` |