Merge pull request 'Referenzwissen ALKIS/WFS und ALKIS-7-Umstellungscheckliste ergänzt' (#3) from doku/alkis-wfs-referenz into unstable

Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
2026-09-04 15:09:25 +02:00
9 changed files with 395 additions and 4 deletions
+5
View File
@@ -14,6 +14,11 @@ Defaults/
# Sie werden vom Menschen im Browser abgesendet und nicht versioniert.
entwuerfe/
# Lokales Referenzmaterial (ALKIS-Schema, OK-AAA-Dokumente, WFS-Sondierung, ~180 MB).
# Herkunft und die daraus destillierte Fassung stehen in docs/wissen/alkis_objektarten.md
# und docs/wissen/wfs_dienste.md. Die Rohdateien werden nicht versioniert.
referenz/
# Lokale, nicht geteilte Dateien
CLAUDE.local.md
AGENTS.local.md
+3
View File
@@ -8,6 +8,8 @@
| `wissen/fallstricke.md` | lebend | bei Überraschungen; vor Arbeiten an WFS, Release, Qt |
| `wissen/glossar.md` | lebend | Fachbegriffe |
| `wissen/externe_dienste.md` | lebend | URLs, Abhängigkeiten |
| `wissen/wfs_dienste.md` | lebend | ALKIS-WFS: Endpunkte, erprobte Anfragen, was der Dienst blockiert |
| `wissen/alkis_objektarten.md` | lebend | ALKIS-Objektarten und Attribute, soweit `sn_verfahrensgebiet` sie nutzt |
| `entscheidungen/` | append-only (ADR) | warum etwas so ist; neue Entscheidung = neue Datei |
| `leitfaden/03_arbeitsweise.md` | stabil | Einstieg für Entwickler, Arbeitszyklus, Checklisten |
| `leitfaden/04_werkzeuge_einrichten.md` | stabil | Einrichtung: Claude Code als CLI und in VS Code; von null zur ersten Aufgabe |
@@ -16,6 +18,7 @@
| `tests/testkatalog.md` | generiert | was die Suite prüft erzeugt von `scripts/testkatalog.py` |
| `tests/*.md` | lebend | Testkonzepte je Fachablauf, mit Mermaid; Vorlage in `vorlagen/` |
| `konzept/07_qgis_tests_plan.md` | Vorschlag | Stufenplan für Tests gegen echtes QGIS |
| `konzept/09_alkis7_umstellung.md` | Prüfliste | ALKIS 6 ↔ 7 (GID 6.0/7.1), was in `sn_verfahrensgebiet` anzupassen ist |
| `konzept/08_repo_einrichten.md` | Prüfliste | Repo auf Gitea anlegen, `stable` und Branch-Schutz |
| `konzept/02_zusammenarbeit_ki_agenten.md` | stabil | Begründung und Aufbau der Zusammenarbeit |
| `analyse/01_projektanalyse.md` | Momentaufnahme 09/2026 | Zusammenspiel der Komponenten, Qualitätsbefund, Risiken |
+113
View File
@@ -0,0 +1,113 @@
# ALKIS 6 → ALKIS 7: Vergleich und Anpassungsbedarf in den Plugins
Stand 04.09.2026. Vorschlag/Prüfliste, noch kein Beschluss. Betroffen ist ausschließlich
**`sn_verfahrensgebiet`** (`functions/*_alkis*.py`); `sn_plan41` spricht kein ALKIS an.
„ALKIS 6/7" meint die GeoInfoDok-Version des AAA-Modells: ALKIS 6 = **GID 6.0**,
ALKIS 7 = **GID 7.1**. Das Referenzmaterial unter `referenz/alkis/` (lokal, nicht versioniert)
ist bereits GID 7.1.2. Verwandte Doku: [`../wissen/wfs_dienste.md`](../wissen/wfs_dienste.md),
[`../wissen/alkis_objektarten.md`](../wissen/alkis_objektarten.md).
---
## Teil 1 Was sich für uns als WFS-/NAS-Konsument ändert
| Thema | ALKIS 6 (GID 6.0) | ALKIS 7 (GID 7.1) | Wirkung auf uns |
|---|---|---|---|
| **NAS-/GML-Namespace** | `http://www.adv-online.de/namespaces/adv/gid/6.0` | `…/adv/gid/7.1` | **Hart.** Jeder fest verdrahtete Namespace findet keine Elemente mehr. |
| **Codelisten** | viele Attribute sind `Enumeration` mit Ganzzahlwert (`2110`) | dieselben Attribute sind **extern verwaltete `CodeList`** (adv-Registry, versioniert); Wert kommt als Code **oder** als Registry-URI, neue Werte ohne Schemaänderung | `artDerFestlegung` kann als URI statt `2110` ankommen; neue FlurbG-nahe Werte (z. B. 2180 Freiwilliger Nutzungstausch) |
| **ISO-Angleichung** | ältere ISO-19100-Stände | Raumbezug/Zeit/Metadaten/Datenqualität an 19107/19108/19115/**19157** angeglichen | `qualitaetsangaben` (`AX_DQ*`) umstrukturiert |
| **Modellpflege** | — | neue Supertypen (`AX_Flurstueck_Kerndaten`), normalisierte Relationsrollen, Anschrift/Lagebezeichnung angepasst | abgeflachte WFS-Feldnamen können sich verschieben |
| **Objektarten** | — | neue/geänderte Objektarten v. a. in Tatsächlicher Nutzung und Bau-/Raum-/Bodenordnung | BROR-Filterung prüfen |
| **Dienst-Infrastruktur** | vorhandener `public_alkis`-WFS | GeoSN stellt i. d. R. neue Capabilities-Version, ggf. neuen Pfad, Parallelbetrieb für Übergangszeit; `outputFormat`-Profilstring ändert sich | Endpunkt/Capabilities neu verifizieren |
**Unverändert:** WFS 2.0.0, GML 3.2, EPSG:25833. Die WAF-Grenzen (POST/GML-Filter blockiert,
URL-Länge, `COUNT`-Limit) sind sächsische Infrastruktur, nicht Schema trotzdem gegen die
neue Instanz neu sondieren (`referenz/wfs/`).
---
## Teil 2 Konkrete Anpassungen
### A. Fest verdrahteter NAS-Namespace — der harte Bruch
- **`functions/grenzpunkt_alkis.py:274`** — `_ADV = "…/gid/6.0"` in `_erstelle_layer_aus_gml`.
Diese Funktion parst PunktortTA- und Grenzpunkt-GML von Hand; gegen einen 7.1-Dienst liefert
`root.findall(".//{…/6.0}…")` nichts → `None` → „keine Grenzpunkte".
**Fix:** Namespace aus dem GML-Wurzelelement ableiten (bzw. Liste bekannter Namespaces
akzeptieren), nicht als Konstante.
- Betrifft auch die verschachtelte Suche `.//{_ADV}genauigkeitsstufe` (Zeile ~340) und
`referenz/wfs/_test_wfs_post.py:8,55` (nur Referenz).
### B. Fest verdrahtete, abgeflachte Attributnamen in `sql=`-Filtern
Der QGIS-WFS-Provider flacht verschachtelte Datentypen zu `eltern_kind_…`-Feldnamen ab.
Ändert GID 7.1 den Schemapfad, ändert sich der Feldname — und jedes `WHERE <name> = …`
liefert **stillschweigend 0 Features**:
| Datei | Feld / Filter |
|---|---|
| `functions/flurstueck_alkis.py:101` | `gemarkung_ax_gemarkung_schluessel_gemarkungsnummer` |
| `functions/verfahrensgebiet_alkis.py` (~112) | `bezeichnung LIKE '<vkz5>%'` auf BROR |
| `functions/verfahrensgebiet_alkis.py:2028` | Liste `BROR_ATTRIBUTE_FELDER` |
| `functions/verfahrensgebiet_edit_service.py:2627` | `FELD_KENNZEICHEN`, `FELD_GEMARKUNG` (Pflichtfelder) |
| `functions/beteiligung_pruefung.py` | `flurstueckskennzeichen`, `zaehler`, `nenner`, `land`, `gemarkungsnummer` |
| `functions/gemarkung_alkis.py` | `schluessel`, `ave_name` (vereinf. Dienst — separat prüfen, Sachsen-eigenes Schema) |
**Aktion:** sobald ein ALKIS-7-Testdienst verfügbar ist, je Objektart `DescribeFeatureType`
ziehen, Feldnamen diffen, alle Namen als benannte Konstanten an **einer** Stelle sammeln;
wo möglich tolerante Feldsuche wie bereits `_erkenne_gehoert_zu_feld`.
### C. `artDerFestlegung` als Codeliste
`functions/verfahrensgebiet_alkis.py` / `verfahrensgebiet_dialoge.py` (`ask_bror_kombinationen`):
falls auf `artderfestlegung` verglichen/gruppiert wird, vor dem Vergleich normalisieren
(letztes URI-Segment nehmen). Werteliste in [`../wissen/alkis_objektarten.md`](../wissen/alkis_objektarten.md)
um neue GID-7.1-Werte ergänzen. Der `bezeichnung LIKE`-Filter bleibt unberührt (String-Attribut).
### D. PunktortTA → Grenzpunkt-Referenz
`grenzpunkt_alkis.py:64` `_GEHOERT_ZU_KANDIDATEN = ["istTeilVon","gehoertZu","gehoertZuAX_Grenzpunkt"]`
ist bereits tolerant — den in GID 7.1 tatsächlich abgeflachten Namen prüfen und ggf. aufnehmen.
`xlink:href="urn:adv:oid:DE…"` sollte bleiben.
### E. Qualitätsangaben
`qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe` (`grenzpunkt_alkis.py:292`) und die
Container-Erkennung gegen die 7.1-DQ-Struktur (ISO 19157) prüfen; Containername kann sich ändern.
### F. Endpunkte konsolidieren und neu sondieren
Die URLs stehen als Literale in vier Dateien (`gemarkung_alkis.py`, `flurstueck_alkis.py`,
`grenzpunkt_alkis.py`, `verfahrensgebiet_alkis.py`). In **ein** Modul ziehen, dann klären,
ob GeoSN den Pfad behält. WAF-Verhalten (POST, KVP-BBOX, ResourceId, `COUNT`-Limit) gegen die
neue Instanz mit den Skripten in `referenz/wfs/` neu testen.
### G. Tests (Projektregel: zuerst der Test, der den Bruch zeigt)
- Für den manuellen GML-Parser gibt es aktuell offenbar **keinen** direkten Test (die
Testdateien enthalten kein GML). Fixtures mit je einem 6.0- und einem 7.1-Namespace-GML
anlegen und parametrisieren.
- `python scripts/run_tests.py sn_verfahrensgebiet --baseline` + `python scripts/testkatalog.py`.
- QGIS-Test gegen den echten ALKIS-7-Dienst im PR dokumentieren.
### H. Doku nachziehen
[`../wissen/wfs_dienste.md`](../wissen/wfs_dienste.md),
[`../wissen/alkis_objektarten.md`](../wissen/alkis_objektarten.md),
[`../wissen/externe_dienste.md`](../wissen/externe_dienste.md),
[`../wissen/fallstricke.md`](../wissen/fallstricke.md); ADR unter `../entscheidungen/` für die
Umstellungsstrategie.
### Strategie
GeoSN fährt ALKIS 6 und 7 vermutlich eine Zeit lang parallel — daher **tolerant** umsetzen
(Namespace aus der Antwort, tolerante Feldsuche), nicht hart umschalten.
---
## Offen / nur am echten ALKIS-7-Dienst klärbar
- exakte abgeflachte Feldnamen in GID 7.1 (`DescribeFeatureType` je Objektart)
- genauer Namespace-Suffix (`7.1` vs. Unterversion)
- ob GeoSN den WFS-Endpunkt / -Pfad wechselt (`GetCapabilities`)
- ob der vereinfachte Dienst (`ave:KatasterBezirk`) mitgezogen wird
- aktualisiertes WAF-Verhalten der neuen Deployment-Instanz
## Nächste Schritte
1. Gitea-Issue in `Plugin_SN_Verfahrensgebiet` anlegen (Entwurf vorbereiten).
2. Sobald ALKIS-7-Testdienst erreichbar: `GetCapabilities` + `DescribeFeatureType` sichern,
Abschnitt B mit echten Feldnamen füllen.
3. Umsetzung als eigener `feature/`-Branch, Namespace-Toleranz zuerst (Abschnitt A).
+4
View File
@@ -58,6 +58,10 @@ spätere Phase und beginnt erst, wenn die Test-Baseline grün ist und das Projek
13. Fachlich offen: Planstand-Versionierung (Plan41 #3), Fachschale aus dem Alternativansatz
(`docs/analyse/00_vergleich_alternativansatz_2026-09-02.md`). Shape-Import mit abweichendem
`FBSchl`-Feldnamen ist seit PR Verfahrensgebiet #45 umgesetzt; QGIS-Test mit echtem DAVID-Export steht aus.
14. **ALKIS-7-Umstellung vorbereiten.** `sn_verfahrensgebiet` trifft an mehreren Stellen ALKIS-6-Annahmen
(fest verdrahteter NAS-Namespace `gid/6.0` in `grenzpunkt_alkis.py`, abgeflachte WFS-Feldnamen in
`sql=`-Filtern). Vergleich 6↔7 und Anpassungsliste: `docs/konzept/09_alkis7_umstellung.md`.
Nächster Schritt: Gitea-Issue in `Plugin_SN_Verfahrensgebiet`.
**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`.
+123
View File
@@ -0,0 +1,123 @@
# ALKIS-Objektarten (soweit die Plugins sie nutzen)
Lebendes Dokument. **Kein** Ersatz für den Objektartenkatalog AAA (OK-AAA) nur die Objektarten und
Attribute, die `sn_verfahrensgebiet` tatsächlich aus den WFS-Diensten liest, mit ihrer praktischen
Bedeutung. Dienste, Anfragen und Grenzen: [`wfs_dienste.md`](wfs_dienste.md).
**Herkunft der Referenz** (lokal unter `referenz/`, nicht versioniert, ~180 MB):
| Datei | Inhalt | Bezug |
|---|---|---|
| `referenz/alkis/OK_AAA-Fachschema_7124316.{pdf,docx}` | Objektartenkatalog AAA-Fachschema, Version 7.1.2 (Stand 01.11.2022) | adv-online, GeoInfoDok |
| `referenz/alkis/OK_AAA-Basisschema_7120975.{pdf,docx}` | AAA-Basisschema 7.1.2 | adv-online |
| `referenz/alkis/OK_AAA-Anwendungsschema_712.{pdf,docx}` | AAA-Anwendungsschema 7.1.2 | adv-online |
| `referenz/alkis/*.cat`, `*.mdl`, `*.pty` | Enterprise-Architect-Exporte des AAA/NAS-Modells und der ISO-191xx-Kataloge | |
| `referenz/alkis/ALKIS_FSK_210/` | ALKIS-Fachschlüssel-/Signaturkatalog Sachsen 2.1.0 (Symbolik FB=Farbe, SW=Schwarzweiß, Anlassarten 0110/0120) | GeoSN |
Beim Aktualisieren der Referenz: neue OK-AAA-Version von adv-online ziehen, diese Tabelle und die
Versionsnummern unten nachziehen.
## Namens- und Filterkonventionen im sächsischen Dienst
- WFS-`TYPENAMES` sind **vollqualifiziert**: `adv:AX_Flurstueck` (Namespace
`http://www.adv-online.de/namespaces/adv/gid/6.0`), Ausnahme vereinfachter Dienst: `ave:KatasterBezirk`.
- In der QGIS-WFS-URI (`sql=SELECT * FROM <lokalname> WHERE …`) wird der **lokale** Name ohne Präfix genutzt.
- Attributnamen im Dienst sind teils **abgeflacht** (Pfad mit `_` verbunden), z. B.
`gemarkung_ax_gemarkung_schluessel_gemarkungsnummer`,
`ausfuehrendestelle_ax_dienststelle_schluessel_stelle`.
- xlink-Referenzen kommen als `xlink:href="urn:adv:oid:DE…"` oder als flacher GML-ID-Wert.
## `AX_Flurstueck` — Flurstück
- **Kennung** 11001 (OK-AAA Fachschema 7.1.2, Kap. 5.1). Objekttyp REO, Geometrie: Fläche (lückenlos,
überschneidungsfrei).
- **Dienst/TypeName:** SF · `adv:AX_Flurstueck`.
- **Filter im Plugin:** `gemarkung_ax_gemarkung_schluessel_gemarkungsnummer = '<4-stellig>'`, je Gemarkung
eine eigene Anfrage (Feature-Limit).
- 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.
## `AX_BauRaumOderBodenordnungsrecht` — Bau-, Raum- oder Bodenordnungsrecht
- **Kennung** 71008 (OK-AAA Fachschema 7.1.2, Kap. 35.9). Objekttyp REO, Geometrie: Fläche.
Fachlich übergeordnetes Gebiet von Flächen mit bodenbezogenen Beschränkungen nach öffentlichen Vorschriften.
- **Dienst/TypeName:** SF · `adv:AX_BauRaumOderBodenordnungsrecht`. Diese Objektart trägt die
**Verfahrensgebiets-Geometrie** für das Plugin.
- **Filter im Plugin:** `bezeichnung LIKE '<vkz5>%'` (erste 5 Stellen der Verfahrenskennziffer).
- **Attribut `artderfestlegung`** (`AX_ArtDerFestlegung_BauRaumOderBodenordnungsrecht`) ist objektbildend.
Für die Flurbereinigung einschlägige Werte:
| Wert | Bedeutung |
|---|---|
| 2100 | Flurbereinigungsgesetz |
| 2110 | Flurbereinigung (§ 1 und § 37 FlurbG) |
| 2120 | Vereinfachtes Flurbereinigungsverfahren (§ 86 FlurbG) |
| 2130 | Unternehmensflurbereinigung (§ 87 oder § 90 FlurbG) |
| 2140 | Beschleunigtes Zusammenlegungsverfahren (§ 91 FlurbG) |
| 2150 | Freiwilliger Landtausch (§ 103a FlurbG) |
| 2210 | Flurneuordnung (LwAnpG) |
| 2220 | Freiwilliger Landtausch (§ 54 LwAnpG) |
| 2230 | Bodenordnungsverfahren (§ 56 LwAnpG) |
| 2200 | Neuvermessungsgebiet innerhalb des Bodenordnungsgebietes |
Vollständige Werteliste: OK-AAA Fachschema 7.1.2, S. 783 ff.
- **Weitere geladene Attribute:** `ausfuehrendestelle_ax_dienststelle_schluessel_stelle`, `adv_name`,
`bezeichnung`, `datumanordnung`, `datumbesitzeinweisung`, `datumrechtskraft`, `datumabgabe`.
## `AX_Grenzpunkt` — Grenzpunkt
- **Kennung** 11003 (OK-AAA Fachschema 7.1.2, Kap. 5.4). Objekttyp **ZUSO** (Zusammengesetztes Objekt)
**keine eigene Geometrie**. Den Raumbezug vermittelt der zugeordnete `PunktortTA` (und/oder `PunktortAU`).
- **Dienst/TypeName:** SF · `adv:AX_Grenzpunkt`.
- **Kein BBOX-Filter möglich.** Abruf ausschließlich über `fes:ResourceId` mit den GML-IDs, die aus
`AX_PunktortTA` stammen (Batches à 100).
- Attribut `gml_id` ist der Join-Schlüssel. `punktkennung` (Kennung PKN) ist ein optionales Ordnungsmerkmal
der katasterführenden Stelle. Das Plugin übernimmt das gelieferte Feldschema dynamisch und stellt den
Attributen im Join-Layer das Präfix `gp_` voran.
## `AX_PunktortTA` — Punktort (tatsächlich, aus Katastervermessung)
- Teil des Raumbezugs-Konzepts (AAA-Basisschema). Trägt die **Koordinate** des Grenzpunkts.
- **Dienst/TypeName:** SF · `adv:AX_PunktortTA`.
- **Geometrieattribut:** `position` (auch der `fes:ValueReference`-Wert für den BBOX-Filter).
- **Referenz auf den Grenzpunkt:** Feldname je NAS-Version verschieden geprüft werden nacheinander
`istTeilVon` (NAS 6.x), `gehoertZu`, `gehoertZuAX_Grenzpunkt`. Wert als `xlink:href` (`urn:adv:oid:DE…`)
oder flach.
- **Qualität:** `adv:qualitaetsangaben/adv:genauigkeitsstufe` → abgeflacht als
`qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe` (nur bei Bedarf extrahiert).
- Räumlich filterbar per KVP-`BBOX` der einzige der vier SF-Typen, bei dem das geht.
## `ave:KatasterBezirk` — Katasterbezirk (vereinfachter Dienst)
- **Kein** AAA-Objekt, sondern die vereinfachte Abgabeform des sächsischen Dienstes. Wird anstelle von
`adv:AX_Gemarkung` genutzt, **weil dieser vereinfachte Dienst tatsächliche Flächengeometrien liefert**
(der NAS-Dienst nicht) und so die Client-seitige Verschneidung mit dem Verfahrensgebiet erlaubt.
- **Dienst/TypeName:** vereinfacht · `ave:KatasterBezirk`.
- **Attribute:** `schluessel` vollständiger Katasterbezirksschlüssel (z. B. `140640001`), **die letzten
4 Stellen** entsprechen der `…gemarkung…gemarkungsnummer` im Flurstücksdienst; `ave_name` Bezeichnung.
- Kein serverseitiger Geometrie- oder BBOX-Filter; Komplettabruf (≈ 2 000 Objekte) und `intersects`.
## Beziehungsübersicht (praktisch genutzt)
```
AX_BauRaumOderBodenordnungsrecht ──(Geometrie)──▶ Verfahrensgebiet
│ intersects
ave:KatasterBezirk (schluessel[-4:]) ──▶ Gemarkungsnummer
AX_Flurstueck (WHERE gemarkung…gemarkungsnummer = …)
BBOX ──▶ AX_PunktortTA (position, istTeilVon/gehoertZu ──xlink──▶ gml_id)
│ ResourceId-Batches
AX_Grenzpunkt (gml_id) ──client-join──▶ „Grenzpunkte (ALKIS)"
```
## Siehe auch
- [`wfs_dienste.md`](wfs_dienste.md) Endpunkte, erprobte Anfragen, Dienst-Grenzen
- [`glossar.md`](glossar.md) Fachbegriffe (ALKIS, NAS, ZUSO, REO, Gemarkung, Flurstückskennzeichen)
- [`externe_dienste.md`](externe_dienste.md)
- `Plugin_SN_Verfahrensgebiet/functions/*_alkis*.py` die nutzende Logik
+5 -2
View File
@@ -1,11 +1,14 @@
# Externe Dienste und Abhängigkeiten
Tiefer: [`wfs_dienste.md`](wfs_dienste.md) (ALKIS-WFS, erprobte Anfragen, Dienst-Grenzen) und
[`alkis_objektarten.md`](alkis_objektarten.md) (Objektarten und Attribute).
| Dienst / Ressource | URL / Ort | Verwendung | Hinweise |
|---|---|---|---|
| Gitea 1.27 (Quellcode, Issues, Releases, Actions) | https://entwicklung.flurneuordnung-sachsen.de/AG_QGIS | alle Repositories | API **lesend ohne Anmeldung** (`/api/v1/...`) dafür `scripts/gitea.py` und Skill `sn-ticket`. Wiki nicht genutzt (Doku liegt versioniert im Repo). Labels sind **organisationsweit** definiert (`/orgs/AG_QGIS/labels`), nicht je Repo `/repos/.../labels` liefert deshalb eine leere Liste. Vorhanden: `Bug`, `Diskussion`, `Feature`, `Konflikt`, `QGIS 3.44`. Meilensteine gibt es keine (geprüft 04.09.2026). Schreibend nur durch Menschen. |
| QGIS-Plugin-Feeds | `Repository/raw/branch/main/plugins*.xml` | Installation in QGIS | stable leer; testing und unstable befüllt |
| ALKIS vereinfacht (WFS) | https://geodienste.sachsen.de/aaa/public_alkis/vereinf/wfs | Gemarkungen, BauRaumOderBodenordnungsrecht | POST/GML-Filter blockiert, URL-Länge begrenzt |
| ALKIS SF (WFS) | https://geodienste.sachsen.de/aaa/public_alkis/sf/wfs | Flurstücke, PunktortTA | Feature-Limits, deshalb Batches |
| ALKIS vereinfacht (WFS) | https://geodienste.sachsen.de/aaa/public_alkis/vereinf/wfs | `ave:KatasterBezirk` → Gemarkungen mit Geometrie | POST/GML-Filter blockiert, kein serverseitiger Filter, Komplettabruf. Details: `wfs_dienste.md` |
| ALKIS SF (WFS) | https://geodienste.sachsen.de/aaa/public_alkis/sf/wfs | `adv:AX_Flurstueck`, `adv:AX_BauRaumOderBodenordnungsrecht`, `adv:AX_PunktortTA`, `adv:AX_Grenzpunkt` | WAF blockiert POST und GML-Filter-XML; GET+KVP-BBOX und `ResourceId` gehen; Feature-Limits → Batches. Details: `wfs_dienste.md`, `alkis_objektarten.md` |
| VLN-Karten-API v2 | https://api.flurneuordnung-sachsen.de/v2 | Plan41-Datensatz je VKZ laden/hochladen | Login E-Mail/Passwort → `X-API-Key`; Zugang über VLN Sachsen |
| LUIS Sachsen (ArcGIS REST) | https://luis.sachsen.de/arcgis/rest/services/... | Fachdaten laut Linkliste (Umwelt, Wasser, Naturschutz, Energie) | 44 Einträge in `assets/Linkliste.xlsx` |
| RAPIS | laut Linkliste | Bauleitplanung, Raumordnung | |
+1 -1
View File
@@ -36,7 +36,7 @@ Kurz, konkret, mit Datum und Quelle. Neue Einträge oben in der passenden Rubrik
## Daten und Dienste
- **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. (Verfahrensgebiet, Code)
- **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)
- **CRS:** Plan41 und VLN-API arbeiten in EPSG:25833. Der Alternativansatz erzeugt EPSG:25832. Für neue Layer 25833 verwenden, bis eine Entscheidung dokumentiert ist.
+4 -1
View File
@@ -15,7 +15,10 @@ Flurbereinigungs-Hintergrund. Ergänzen, wenn ein Begriff im Issue erklärt werd
| **BROR / BROBOR** | ALKIS-Objektart `BauRaumOderBodenordnungsrecht`; enthält Verfahrensgebiete als Objekte; Suche per VKZ oder Landkreis |
| **Gemarkung** | Katasterbezirk; Flurstücke werden gemarkungsweise abgerufen (Gemarkungsschlüssel) |
| **Flurstück (Flst)** | Katasterparzelle; Flurstückskennzeichen (mit Länderkennung) |
| **PunktortTA** | ALKIS-Punktorte (Grenzpunkte) im Tatsächlichen Ausgleich; Basis der Grenzpunkt- und Knickpunktprüfung |
| **PunktortTA** | ALKIS-Objektart `AX_PunktortTA` „Punktort, tatsächlich" aus der Katastervermessung; trägt die Koordinate des Grenzpunkts, Basis der Grenzpunkt- und Knickpunktprüfung |
| **NAS** | Normbasierte Austauschschnittstelle des AAA-Modells (GML-Profil); Format der ALKIS-WFS-Antworten |
| **ZUSO / REO** | AAA-Objekttypen: ZUSO = Zusammengesetztes Objekt (z. B. `AX_Grenzpunkt`, ohne eigene Geometrie), REO = Raumbezogenes Elementarobjekt (z. B. `AX_Flurstueck`) |
| **OK-AAA** | Objektartenkatalog des AAA-Modells (GeoInfoDok); Referenz für ALKIS-Objektarten und -Attribute, lokal unter `referenz/alkis/` |
| **Knickpunkt** | Eckpunkt des Verfahrensgebietsumrings; Prüfung, ob zu jedem Knickpunkt ein Grenzpunkt existiert |
| **NoBIS** | Fachverfahren (Neuordnungs-Bodenordnungs-Informationssystem); liefert Shape-Exporte mit `FBSchl` |
| **FBSchl** | Fachbedeutungsschlüssel im NoBIS-Shape: `901/10110F` Neuordnungsgebiet, `901/10120F` Neuvermessungsgebiet |
+137
View File
@@ -0,0 +1,137 @@
# WFS-Dienste (ALKIS Sachsen)
Lebendes Dokument. Was die Plugins an WFS-Diensten ansprechen, wie sich diese Dienste **tatsächlich**
verhalten (nicht wie die Norm es vorsieht) und welche Anfragen erprobt funktionieren.
Betrifft ausschließlich **`sn_verfahrensgebiet`** (`functions/*_alkis*.py`). `sn_plan41` nutzt kein ALKIS/WFS,
sondern die VLN-Karten-API. Objektarten und Attribute im Detail: [`alkis_objektarten.md`](alkis_objektarten.md).
Quelle der Erkenntnisse: Sondierungsskripte in `referenz/wfs/` (nicht versioniert) und der Code selbst.
## Die drei Endpunkte
| Kürzel im Code | URL | WFS-Version | Geometrie | Verwendung |
|---|---|---|---|---|
| „vereinfacht" (`ALKIS_VEREINF_URL`) | `https://geodienste.sachsen.de/aaa/public_alkis/vereinf/wfs` | 2.0.0 | ja | `ave:KatasterBezirk` → Gemarkungen mit Fläche |
| „SF" (`ALKIS_SF_URL`) | `https://geodienste.sachsen.de/aaa/public_alkis/sf/wfs` | 2.0.0 | teils | `adv:AX_Flurstueck`, `adv:AX_BauRaumOderBodenordnungsrecht`, `adv:AX_PunktortTA`, `adv:AX_Grenzpunkt` |
| „NAS" (nur erwähnt) | | | | `adv:AX_Gemarkung` hätte **keine** Geometrie, deshalb wird stattdessen `ave:KatasterBezirk` genommen |
CRS durchgängig **EPSG:25833** (ETRS89 / UTM 33N). In KVP-Parametern als `urn:ogc:def:crs:EPSG::25833`,
in der QGIS-WFS-URI als `srsname='EPSG:25833'`.
## Was der Dienst blockiert die harten Grenzen
Ein Web Application Firewall vor `geodienste.sachsen.de` schränkt den Dienst gegenüber der WFS-2.0-Norm ein:
| Was | Verhalten | Beleg |
|---|---|---|
| **POST** (`GetFeature` als XML-Body) | blockiert | `referenz/wfs/_test_wfs_post.py` |
| **`FILTER`-XML mit GML-`Envelope`/`BBOX`** in der GET-URL | blockiert | `referenz/wfs/_test_wfs_bbox.py`, `grenzpunkt_alkis.py` Kopf |
| **KVP-Parameter `BBOX=minx,miny,maxx,maxy,crs`** | **funktioniert** so wird PunktortTA räumlich gefiltert | `_punktort_ta_bbox_param()` |
| **`FILTER` mit `fes:ResourceId rid="…"`** in der GET-URL | funktioniert (`ImplementsResourceId=TRUE`) | `_test_wfs_get.py`, Grenzpunkt-Batches |
| **URL-Länge** | ~8192 Bytes; darüber 414/Abbruch | Batchgröße 100 IDs (~54 Byte/ID URL-kodiert) |
| **`COUNT`** | Serverlimit, im Code auf 20 000 gesetzt (`_MAX_FEATURES`) | `grenzpunkt_alkis.py` |
| **Serverseitiger Filter auf `gehoertZu`/`istTeilVon`** | nicht möglich (`ErrorInPropertyName`) | `grenzpunkt_alkis.py` Kopf |
| **`AX_Grenzpunkt` per BBOX** | nicht möglich Objektart ohne eigene Geometrie | siehe unten |
Folgerung: **Nicht „vereinfachen", ohne gegen den Dienst zu testen.** Die scheinbar umständlichen
Mehrschritt-Strategien (BBOX → PunktortTA → GML-IDs → Grenzpunkt-Batches → Client-Join; Flurstücke
gemarkungsweise einzeln) sind die Antwort auf genau diese Grenzen.
## Anfragen je Objektart (erprobt)
### `ave:KatasterBezirk` (vereinfachter Dienst) → Gemarkungen
QGIS-WFS-Layer, **ohne** serverseitigen Filter (Dienst kann es nicht), danach Client-seitige Verschneidung
per `QgsGeometry.intersects` mit der Verfahrensgebiets-Geometrie:
```
url='https://geodienste.sachsen.de/aaa/public_alkis/vereinf/wfs'
typename='ave:KatasterBezirk' srsname='EPSG:25833'
```
Attribute: `schluessel` (voller Katasterbezirksschlüssel, **letzte 4 Stellen = Gemarkungsnummer**),
`ave_name` (Bezeichnung). Sachsen hat ≈ 2 000 Katasterbezirke der Komplettabruf ist vertretbar.
### `adv:AX_BauRaumOderBodenordnungsrecht` (SF) → Verfahrensgebiet
Serverseitiger Attributfilter über die QGIS-WFS-URI (`sql=`):
```
url='…/sf/wfs' typename='adv:AX_BauRaumOderBodenordnungsrecht' srsname='EPSG:25833'
sql=SELECT * FROM AX_BauRaumOderBodenordnungsrecht WHERE bezeichnung LIKE '<vkz5>%'
```
`<vkz5>` = die **ersten 5 Stellen** der Verfahrenskennziffer (`get_variable("verfahrensnummer")[:5]`);
die Daten im Dienst führen teils abweichende Suffixe. Geladene Attribute:
`artderfestlegung`, `ausfuehrendestelle_ax_dienststelle_schluessel_stelle`, `adv_name`, `bezeichnung`,
`datumanordnung`, `datumbesitzeinweisung`, `datumrechtskraft`, `datumabgabe`.
Gruppierung im Plugin nach `(adv_name, bezeichnung)`.
### `adv:AX_Flurstueck` (SF)
**Eine WFS-Anfrage pro Gemarkung** (Sammelabfrage mit mehreren Nummern läuft ins Feature-Limit),
Ergebnisse in einen Memory-Layer zusammengeführt:
```
url='…/sf/wfs' typename='adv:AX_Flurstueck' srsname='EPSG:25833'
sql=SELECT * FROM AX_Flurstueck
WHERE gemarkung_ax_gemarkung_schluessel_gemarkungsnummer = '<gemarkungsnummer4>'
```
### `adv:AX_PunktortTA` (SF) → Trägerpunkt für Grenzpunkte
Roh-GET mit KVP-`BBOX`, GML-Antwort wird selbst geparst (`xml.etree`):
```
SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature
&TYPENAMES=adv:AX_PunktortTA
&SRSNAME=urn:ogc:def:crs:EPSG::25833
&COUNT=20000
&BBOX=<minx>,<miny>,<maxx>,<maxy>,urn:ogc:def:crs:EPSG::25833
```
Geometrieattribut `position`. Referenz auf den Grenzpunkt: Feldname je NAS-Version unterschiedlich
Kandidaten in dieser Reihenfolge geprüft: `istTeilVon` (NAS 6.x), `gehoertZu`, `gehoertZuAX_Grenzpunkt`.
Wert kommt als `xlink:href` (`urn:adv:oid:DE…`) oder flach. Optional wird
`adv:qualitaetsangaben/adv:genauigkeitsstufe` in das Feld
`qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe` gezogen.
### `adv:AX_Grenzpunkt` (SF)
Kein BBOX (ZUSO ohne eigene Geometrie). Abruf über die aus PunktortTA gewonnenen GML-IDs,
**Batches à 100**, GET mit `ResourceId`-Filter:
```
SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature
&TYPENAMES=adv:AX_Grenzpunkt&COUNT=20000
&FILTER=<fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0">
<fes:ResourceId rid="DE…"/> … (bis zu 100)
</fes:Filter>
```
Danach Client-seitiger Join `PunktortTA.<referenzfeld>``AX_Grenzpunkt.gml_id`; Grenzpunkt-Attribute
im Ergebnis mit Präfix `gp_`.
## Fehlerantworten, die im Betrieb auftauchen
| Antwort | Bedeutung | Reaktion im Code |
|---|---|---|
| HTTP 403 / HTML-Seite statt XML | WAF hat POST oder GML-XML-Filter geblockt | auf GET + KVP/ResourceId ausweichen |
| `ExceptionReport` mit `ErrorInPropertyName` | Attribut ist nicht serverseitig filterbar | Attribut client-seitig filtern |
| gültiger Layer, `featureCount() == 0` | Dienst liefert ohne (unterstützten) Filter nichts | Diagnosemeldung, leere Liste, manueller Fallback |
| HTTP 414 | URL zu lang | Batchgröße senken |
## Offene Punkte
- Die vier Skripte in `referenz/wfs/` sind Wegwerf-Sondierungen. Wenn Bedarf besteht, sie regelmäßig
laufen zu lassen (Dienst-Regression erkennen), gehören sie als `scripts/wfs_probe.py` ins Projektwissen
mit Netzkennzeichnung, kein Unittest.
- `ave:KatasterBezirk` vs. Schreibweise `Katasterbezirk`/`KatasterBezirk`: im Code uneinheitlich
dokumentiert, maßgeblich ist der Wert in `gemarkung_alkis.py` (`ave:KatasterBezirk`).
## Siehe auch
- [`alkis_objektarten.md`](alkis_objektarten.md) Objektarten und Attribute
- [`externe_dienste.md`](externe_dienste.md) alle externen Dienste im Überblick
- [`fallstricke.md`](fallstricke.md) Abschnitt „Daten und Dienste"
- `referenz/alkis/` (lokal, nicht versioniert) OK-AAA 7.1.2, ALKIS-FSK 2.1.0