Merge pull request 'Flurstückssuche im Tab „Eigentümer“ (Verfahrensgebiet #56) dokumentiert' (#31) from docs/56-flurstueckssuche into main

Reviewed-on: #31
This commit was merged in pull request #31.
This commit is contained in:
2026-10-06 10:51:26 +00:00
5 changed files with 212 additions and 18 deletions
+4 -2
View File
@@ -84,8 +84,9 @@ Legende: ⚠ = über 600 Zeilen, nie komplett laden, per `grep -n "def "` navigi
| 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/dockwidget.py` | 60 | Tabs `WorkingTab`, `EigentuemerTab`, `PrintTab`, `SettingsTab`; injiziert Services per `set_services()` |
| `ui/tabs/working_tab.py` ⚠ | 820 | Tab „Bearbeitung“: Buttons und Handler für ALKIS/Shape laden, Gemarkungen, Flurstücke, Grenzpunkte, Beteiligung, Statistik; hält viel Ablauflogik |
| `ui/tabs/eigentuemer_tab.py` | 104 | Tab „Eigentümer“ (#56): Flurstückssuche – Eingabe, Hinweise, Treffer auswählen und hinzoomen |
| `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 |
@@ -93,12 +94,13 @@ Legende: ⚠ = über 600 Zeilen, nie komplett laden, per `grep -n "def "` navigi
| `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/flurstueck_suche.py` | 175 | Flurstückssuche im Layer „Flurstücke“ über das `flurstueckskennzeichen`; Gemarkungsname über Layer „Gemarkungen“ |
| `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) |
| `tests/` | 14 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 |
File diff suppressed because one or more lines are too long
+48 -6
View File
@@ -9,17 +9,17 @@ selbst (Docstrings) und aus der Testbaseline.
Stand der Baseline: `docs/status/testbaseline.json` (SHA-256 `aeabc946a7f3`)
Gesamt: 3 Pakete, 60 Testdateien, 744 Testfälle – 701 grün, 35 rot (Baseline), 8 übersprungen.
Mit Beschreibung (Docstring): 599 von 744 (81 %).
Gesamt: 3 Pakete, 62 Testdateien, 762 Testfälle – 719 grün, 35 rot (Baseline), 8 übersprungen.
Mit Beschreibung (Docstring): 617 von 762 (81 %).
## Zusammenfassung
| Paket | Testdateien | Testfälle | grün | rot (Baseline) | übersprungen | mit Beschreibung |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| `sn_basis` | 43 | 490 | 490 | 0 | 0 | 490 von 490 (100 %) |
| `sn_verfahrensgebiet` | 12 | 210 | 168 | 34 | 8 | 108 von 210 (51 %) |
| `sn_verfahrensgebiet` | 14 | 228 | 186 | 34 | 8 | 126 von 228 (55 %) |
| `sn_plan41` | 5 | 44 | 43 | 1 | 0 | 1 von 44 (2 %) |
| **Summe** | **60** | **744** | **701** | **35** | **8** | **599 von 744 (81 %)** |
| **Summe** | **62** | **762** | **719** | **35** | **8** | **617 von 762 (81 %)** |
### Legende
@@ -1071,7 +1071,7 @@ Testgruppen:
## Paket `sn_verfahrensgebiet`
Fachplugin, Ordner `Plugin_SN_Verfahrensgebiet` – 12 Testdateien mit 210 Testfällen (168 grün, 34 rot, 8 übersprungen).
Fachplugin, Ordner `Plugin_SN_Verfahrensgebiet` – 14 Testdateien mit 228 Testfällen (186 grün, 34 rot, 8 übersprungen).
### `Plugin_SN_Verfahrensgebiet/tests/test_beteiligung_pruefung.py`
@@ -1128,6 +1128,24 @@ Testgruppen:
| `TestDockWidget.test_init_tabs_with_services_injects_available_services` | — (Docstring fehlt) | grün |
| `TestDockWidget.test_init_tabs_with_services_reports_errors` | — (Docstring fehlt) | grün |
### `Plugin_SN_Verfahrensgebiet/tests/test_eigentuemer_tab.py`
Worum es in der Datei geht: Tests für den Tab „Eigentümer“ – Flurstückssuche (#56).
Testgruppen:
- `TestFlurstueckSuchen` (5 Testfälle): — (Docstring fehlt)
- `TestDockWidgetTabs` (1 Testfälle): — (Docstring fehlt)
| Testfall | prüft | Status |
| --- | --- | --- |
| `TestFlurstueckSuchen.test_ohne_flurstueckslayer_erscheint_hinweisdialog` | Prüft, dass ohne Layer „Flurstücke“ ein Dialog zum Laden von Verfahrensgebiet und Flurstücken erscheint. | grün |
| `TestFlurstueckSuchen.test_eingabefehler_als_warnung` | Prüft, dass eine ungültige Eingabe als Warnung in der Meldungsleiste erscheint, nicht als Dialog. | grün |
| `TestFlurstueckSuchen.test_kein_treffer` | Prüft, dass ohne Treffer ein Hinweis erscheint und keine Auswahl gesetzt wird. | grün |
| `TestFlurstueckSuchen.test_treffer_werden_ausgewaehlt_und_angezoomt` | Prüft, dass Treffer im Flurstückslayer ausgewählt, angezoomt und gemeldet werden. | grün |
| `TestFlurstueckSuchen.test_ohne_kartenansicht_bleibt_auswahl` | Prüft, dass die Auswahl auch ohne Kartenansicht gesetzt und gemeldet wird. | grün |
| `TestDockWidgetTabs.test_tab_ist_im_dockwidget_eingetragen` | Prüft, dass der Tab „Eigentümer“ im DockWidget direkt nach dem Bearbeitungs-Tab steht. | grün |
### `Plugin_SN_Verfahrensgebiet/tests/test_flurstueck_alkis.py`
Worum es in der Datei geht: Unit-Tests für das flurstueck_alkis-Modul.
@@ -1154,6 +1172,30 @@ Testgruppen:
| `TestFlurstueckAlkisAnhaengenDedup.test_append_ohne_kennzeichen_feld_haengt_alles_an` | Prüft, dass ohne flurstueckskennzeichen-Feld weiterhin alle Features angehängt werden (Rückfallverhalten). | grün |
| `TestFlurstueckAlkisAnhaengenDedup.test_ohne_schluessel_abfrage_append_dedup` | ohne_schluessel_abfrage=True: Anhängen dedupliziert trotzdem, ohne nach Schlüsseln zu fragen (#47). | grün |
### `Plugin_SN_Verfahrensgebiet/tests/test_flurstueck_suche.py`
Worum es in der Datei geht: Tests für die Flurstückssuche im Layer „Flurstücke“ (#56).
Testgruppen:
- `TestEingabe` (6 Testfälle): — (Docstring fehlt)
- `TestSuche` (6 Testfälle): — (Docstring fehlt)
| Testfall | prüft | Status |
| --- | --- | --- |
| `TestEingabe.test_flurstuecksnummer_mit_und_ohne_nenner` | Prüft, dass Zähler und Nenner getrennt und führende Nullen entfernt werden. | grün |
| `TestEingabe.test_ungueltige_flurstuecksnummer` | Prüft, dass leere oder unzulässige Flurstücksnummern abgelehnt werden. | grün |
| `TestEingabe.test_kennzeichen_zerlegen` | Prüft, dass Gemarkung, Zähler und Nenner aus dem ALKIS-Kennzeichen gelesen werden. | grün |
| `TestEingabe.test_gemarkungsnummer_aus_ziffern` | Prüft, dass Ziffern als Gemarkungsnummer gelten, auch ohne führende Nullen oder als langer Schlüssel. | grün |
| `TestEingabe.test_gemarkungsname_ueber_gemarkungslayer` | Prüft, dass ein Gemarkungsname ohne Rücksicht auf Großschreibung in alle passenden Nummern übersetzt wird. | grün |
| `TestEingabe.test_gemarkungsname_ohne_layer_oder_unbekannt` | Prüft, dass ein Name ohne Gemarkungslayer oder ohne Treffer eine verständliche Meldung ergibt. | grün |
| `TestSuche.test_mit_nenner_genau_ein_treffer` | Prüft, dass mit Nenner nur das passende Flurstück der Gemarkung gefunden wird. | grün |
| `TestSuche.test_ohne_nenner_alle_mit_diesem_zaehler` | Prüft, dass ohne Nenner alle Flurstücke mit dem Zähler gefunden werden, aber nur in der gesuchten Gemarkung. | grün |
| `TestSuche.test_kein_treffer` | Prüft, dass ein nicht vorhandenes Flurstück eine leere Trefferliste ergibt. | grün |
| `TestSuche.test_layer_ohne_kennzeichenfeld` | Prüft, dass ein Flurstückslayer ohne Feld „flurstueckskennzeichen“ gemeldet wird. | grün |
| `TestSuche.test_fehlender_flurstueckslayer_bricht_ab` | Prüft, dass die Suche ohne Layer „Flurstücke“ mit dem Hinweis abbricht, zuerst Verfahrensgebiet und Flurstücke zu laden. | grün |
| `TestSuche.test_suche_im_projekt_mit_gemarkungsname` | Prüft, dass die Suche im Projekt den Gemarkungsnamen auflöst und Layer samt Treffern liefert. | grün |
### `Plugin_SN_Verfahrensgebiet/tests/test_gemarkung_alkis.py`
Worum es in der Datei geht: Unit-Tests für `sn_verfahrensgebiet.functions.gemarkung_alkis`.
@@ -1563,7 +1605,7 @@ dann verschwindet er hier von selbst.
Keine Lücken.
### `sn_verfahrensgebiet` – 102 von 210 Testfällen ohne Beschreibung
### `sn_verfahrensgebiet` – 102 von 228 Testfällen ohne Beschreibung
#### `Plugin_SN_Verfahrensgebiet/tests/test_beteiligung_pruefung.py` (25 von 25)
@@ -0,0 +1,84 @@
# Testkonzept: Flurstückssuche im Tab „Eigentümer“
Plugin: `sn_verfahrensgebiet` · Stand: 06.10.2026 · Pflege: bei jeder Änderung an diesem Ablauf
## Worum es fachlich geht
Im Termin mit einem Eigentümer soll die Sachbearbeitung ein Flurstück schnell auf der Karte zeigen können.
Sie gibt Gemarkung und Flurstücksnummer ein, das Plugin wählt das Flurstück im geladenen Flurstückslayer aus
und springt dorthin. Gesucht wird nur in den Flurstücken, die vorher mit dem Verfahrensgebiet aus ALKIS geladen
wurden. So muss im Tab keine Gemarkung aus ganz Sachsen ausgewählt werden.
Die Eigentümersuche aus Issue Verfahrensgebiet #56 folgt in weiteren Schritten und wird hier ergänzt.
## Der Ablauf
```mermaid
flowchart TD
A["1 Anwender gibt Gemarkung<br/>und Flurstücksnummer ein"] --> B{"2 Flurstückslayer<br/>im Projekt?"}
B -->|nein| C["Hinweis: zuerst Verfahrensgebiet<br/>und Flurstücke aus ALKIS laden"]
B -->|ja| D{"3 Flurstücksnummer lesbar?<br/>z. B. 562 oder 12/3"}
D -->|nein| E["Hinweis zur Schreibweise"]
D -->|ja| F{"4 Gemarkung als Nummer<br/>oder als Name?"}
F -->|Nummer| H["5 Flurstücke vergleichen"]
F -->|Name| G{"Gemarkungslayer geladen<br/>und Name darin?"}
G -->|nein| E2["Hinweis: Nummer eingeben<br/>oder Gemarkungen laden"]
G -->|ja| H
H --> I{"6 Treffer?"}
I -->|nein| J["Hinweis: nicht gefunden"]
I -->|ja| K["7 Treffer auswählen,<br/>hinzoomen, aufblinken"]
style C fill:#fff4e6,stroke:#d9822b
style E fill:#fff4e6,stroke:#d9822b
style E2 fill:#fff4e6,stroke:#d9822b
```
## Was geprüft wird
Die Tests liegen in `Plugin_SN_Verfahrensgebiet/tests/test_flurstueck_suche.py` (Suchlogik) und
`tests/test_eigentuemer_tab.py` (Bedienung im Tab).
| # | Schritt | Wird geprüft durch | Ebene |
|---|---|---|---|
| — | Tab erscheint nach „Bearbeitung“ | `test_tab_ist_im_dockwidget_eingetragen` | Mock |
| 2 | Kein Flurstückslayer: Suche bricht ab | `test_fehlender_flurstueckslayer_bricht_ab` | Mock |
| 2 | … und der Hinweis kommt als Dialog | `test_ohne_flurstueckslayer_erscheint_hinweisdialog` | Mock |
| 3 | Zähler und Nenner lesen, führende Nullen | `test_flurstuecksnummer_mit_und_ohne_nenner` | Mock |
| 3 | Unlesbare Nummer abweisen | `test_ungueltige_flurstuecksnummer`, `test_eingabefehler_als_warnung` | Mock |
| 4 | Gemarkungsnummer, auch ohne Nullen oder als langer Schlüssel | `test_gemarkungsnummer_aus_ziffern` | Mock |
| 4 | Gemarkungsname, auch mehrfach vorkommend | `test_gemarkungsname_ueber_gemarkungslayer` | Mock |
| 4 | Name ohne Gemarkungslayer oder unbekannt | `test_gemarkungsname_ohne_layer_oder_unbekannt` | Mock |
| 5 | Flurstückskennzeichen zerlegen | `test_kennzeichen_zerlegen` | Mock |
| 5 | Layer ohne Kennzeichenfeld | `test_layer_ohne_kennzeichenfeld` | Mock |
| 6 | Mit Nenner genau ein Treffer | `test_mit_nenner_genau_ein_treffer` | Mock |
| 6 | Ohne Nenner alle mit diesem Zähler, nur in der Gemarkung | `test_ohne_nenner_alle_mit_diesem_zaehler` | Mock |
| 6 | Kein Treffer | `test_kein_treffer` (Logik), `test_kein_treffer` (Tab) | Mock |
| 7 | Auswahl, Zoom, Aufblinken | `test_treffer_werden_ausgewaehlt_und_angezoomt` | Mock |
| 7 | Auswahl auch ohne Kartenansicht | `test_ohne_kartenansicht_bleibt_auswahl` | Mock |
| — | Sieht das in QGIS richtig aus? | manueller Test | manuell |
Ebene: `Mock` (ohne QGIS, Sekunden) · `QGIS` (gegen echtes QGIS) · `manuell` (Mensch in QGIS).
## Fachliche Sonderfälle
| Sonderfall | Kommt vor bei | Wird geprüft durch |
|---|---|---|
| Buchstaben-Nenner (`12/a`) | ältere Flurstücke | `test_mit_nenner_genau_ein_treffer`, `test_kennzeichen_zerlegen` |
| Gleichnamige Gemarkungen | verbreitete Ortsnamen in mehreren Landkreisen | `test_gemarkungsname_ueber_gemarkungslayer` |
| Gemarkungsschlüssel mit Landesnummer (`140268`) | kopiert aus anderen Programmen | `test_gemarkungsnummer_aus_ziffern` |
| Flurstücke mit leerem Kennzeichen | unvollständige Daten | `test_ohne_nenner_alle_mit_diesem_zaehler` (Feature ohne Kennzeichen wird übersprungen) |
| Im Flurstückslayer ist schon etwas ausgewählt | Verfahrensgebiet aus der Flurstücksauswahl bilden | `test_treffer_werden_ausgewaehlt_und_angezoomt`: Die Suche ersetzt die Auswahl, wie die Suchen in QGIS selbst |
## Bewusst nicht getestet
| Was | Warum | Wie stattdessen abgesichert |
|---|---|---|
| Zoomen und Aufblinken in der Kartenansicht | QGIS-Funktionen (`zoomToSelected`, `flashFeatureIds`), im Mock-Modus gibt es keine Karte | manueller Test in QGIS |
| Aussehen des Tabs | nicht sinnvoll automatisiert prüfbar | manueller Test |
| Echter Flurstückslayer aus dem ALKIS-WFS | kein Netzwerk in Tests | Aufbau des Kennzeichens in `../wissen/alkis_objektarten.md`, manueller Test |
## Bekannte Lücken
| Lücke | Auswirkung | Issue |
|---|---|---|
| Der manuelle Test in QGIS steht aus | Zoom auf sehr kleine Flurstücke und das Aufblinken sind nicht gesehen | Verfahrensgebiet #56 |
+8
View File
@@ -37,6 +37,14 @@ Versionsnummern unten nachziehen.
- Praktisch relevant: das Flurstückskennzeichen ist objektbildend; jedes Flurstück gehört zu genau einer
Gemarkung bzw. Flur/Gemarkungsteil. Das Plugin übernimmt das komplette Feldschema des WFS-Layers in den
Memory-Layer, ohne Attribute fest zu benennen.
- **Aufbau von `flurstueckskennzeichen`** (20 Zeichen, unbesetzte Teile mit `_` gefüllt), am Dienst geprüft
am 06.10.2026: `14 0268 ___ 00562 ____ 00` = Land (2), Gemarkungsnummer (4), Flur (3, in Sachsen unbesetzt),
Zähler (5), Nenner (4, auch Buchstaben wie `000a`), Folge (2). Die Flurstückssuche (Verfahrensgebiet #56)
vergleicht deshalb dieses Kennzeichen und nicht die von QGIS abgeflachten Einzelfelder
(`flurstuecksnummer/…/zaehler`), deren Namen vom WFS-Provider abhängen.
- **Keine Eigentümer- oder Buchungsangaben:** Der öffentliche Dienst verweist nur per `istGebucht` auf ein
Buchungsblatt-Objekt, das er selbst nicht ausliefert. Eine Zuordnung Eigentümer ↔ Flurstück braucht eine eigene
Quelle (Verfahrensgebiet #56, dort zurückgestellt).
## `AX_BauRaumOderBodenordnungsrecht` — Bau-, Raum- oder Bodenordnungsrecht