Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5004a8d5bf | ||
|
|
3bde666d96 | ||
|
|
e0660aba86 | ||
|
|
84e03d208c | ||
|
|
341b9ab1c4 | ||
|
|
f7661a5d25 | ||
|
|
1aea40d028 | ||
|
|
45a8ce37de | ||
|
|
951b9075fe | ||
|
|
c260ccc2d6 | ||
|
|
49d30eea22 | ||
|
|
0ac0757e42 | ||
|
|
e267d51607 | ||
|
|
003ad1957b | ||
|
|
821bb0640e | ||
|
|
04f2a49c13 | ||
|
|
eac3b44470 | ||
|
|
0a906d3ac7 | ||
|
|
39f8209b9d | ||
|
|
3c0e6e5a19 | ||
|
|
c93776d19e |
@@ -1,3 +1,8 @@
|
|||||||
|
- Bugfix: Nach dem Laden des Verfahrensgebiets (ALKIS oder Shape) sprang die Karte an die falsche Stelle, wenn ein anderes Projekt-KBS als EPSG:25833 eingestellt war. Der Zoom rechnet die Ausdehnung jetzt in das KBS der Kartenansicht um (`zoom_auf_layer` aus sn_basis, setzt sn_basis mit Basis #99 voraus) (Basis #99)
|
||||||
|
- Neu: Grenzpunkte aus ALKIS werden nach dem Laden im ALKIS-Stil dargestellt (styles/alkis_grenzpunkte.qml), statt ungestylt zu bleiben (#53)
|
||||||
|
- Intern: Tests von TestFlurstueckAlkis an die seit längerem geänderte Ladelogik angeglichen (Mocks zeigten noch auf die alte Ein-Query-/Zwei-Knopf-Variante), bbox-Dokumentation in flurstueck_alkis.py korrigiert (bbox wird nicht mehr ausgewertet) – keine Verhaltensänderung (Test-Audit #16)
|
||||||
|
- Intern: Der Button "aus gewählten Gemarkungen laden" nutzt jetzt dieselbe Ladelogik wie "Flurstücke laden" (flurstueck_alkis) statt einer eigenen, parallelen Implementierung – konsolidiert drei bisher getrennte Code-Pfade zum Flurstücke-Laden auf einen (#47)
|
||||||
|
- Bugfix: Flurstücke aus ALKIS an bestehenden Layer anhängen überspringt jetzt bereits vorhandene Flurstücke (Abgleich über flurstueckskennzeichen), statt sie doppelt zu laden – betrifft sowohl den Dialog in "Flurstücke laden" als auch den Button "aus gewählten Gemarkungen laden" (#28)
|
||||||
- Fortschrittsdialog beim Laden aus ALKIS schließt jetzt zuverlässig bei jedem Abbruch (Bugfix)
|
- Fortschrittsdialog beim Laden aus ALKIS schließt jetzt zuverlässig bei jedem Abbruch (Bugfix)
|
||||||
- Fortschrittsanzeige beim Laden aus ALKIS in zwei Dialoge aufgeteilt (Suche / eigentlicher Ladevorgang), inkl. eigenem Suchschritt
|
- Fortschrittsanzeige beim Laden aus ALKIS in zwei Dialoge aufgeteilt (Suche / eigentlicher Ladevorgang), inkl. eigenem Suchschritt
|
||||||
- Mehrfachauswahl bei mehreren BauRaumOderBodenordnungsrecht-Treffern zur Verfahrensnummer (gemeinsames Laden/Verschmelzen mehrerer Objekte)
|
- Mehrfachauswahl bei mehreren BauRaumOderBodenordnungsrecht-Treffern zur Verfahrensnummer (gemeinsames Laden/Verschmelzen mehrerer Objekte)
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
Lädt Flurstücke aus dem ALKIS-WFS-Dienst (``adv:AX_Flurstueck``) anhand von
|
Lädt Flurstücke aus dem ALKIS-WFS-Dienst (``adv:AX_Flurstueck``) anhand von
|
||||||
Gemarkungsschlüsseln, die der Nutzer interaktiv eingibt.
|
Gemarkungsschlüsseln, die der Nutzer interaktiv eingibt.
|
||||||
|
|
||||||
Der WFS-Layer wird direkt (nicht als Memory-Layer) ins Projekt geladen,
|
Für jede Gemarkungsnummer wird eine eigene WFS-Anfrage gestellt (umgeht das
|
||||||
da die einzelnen Features für die spätere Auswahl benötigt werden.
|
WFS-Feature-Limit einer Gesamtabfrage); alle Ergebnisse werden anschließend in
|
||||||
|
einem gemeinsamen Memory-Layer zusammengeführt.
|
||||||
|
|
||||||
**Erweiterung gegenüber dem Original:**
|
**Erweiterung gegenüber dem Original:**
|
||||||
|
|
||||||
@@ -16,10 +17,11 @@ da die einzelnen Features für die spätere Auswahl benötigt werden.
|
|||||||
- ``vorgabe_namen``: Zugehörige Bezeichnungen, die im Dialog als Hinweis
|
- ``vorgabe_namen``: Zugehörige Bezeichnungen, die im Dialog als Hinweis
|
||||||
angezeigt werden (kein eigenständiges Feld, nur Anzeigetext).
|
angezeigt werden (kein eigenständiges Feld, nur Anzeigetext).
|
||||||
|
|
||||||
- ``bbox``: Optionaler BBox-Parameter, der – sofern übergeben – als
|
- ``bbox``: Nicht mehr verwendet. Die Flurstück-Geometrie kommt ausschließlich
|
||||||
zusätzlicher serverseitiger Filter in die WFS-URI eingebettet wird. So
|
aus dem ALKIS-WFS je Gemarkung; eine BBox filtert höchstens vorgelagert die
|
||||||
werden ausschließlich Flurstücke geladen, die den Verfahrensgebiets-Rahmen
|
Gemarkungsauswahl (siehe ``gemarkung_alkis.py``), nie die Flurstücke selbst.
|
||||||
überlappen.
|
Der Parameter bleibt nur aus Gründen der Signatur-Rückwärtskompatibilität
|
||||||
|
erhalten.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
@@ -37,6 +39,7 @@ from sn_verfahrensgebiet.functions.verfahrensgebiet_alkis import LoadStatus
|
|||||||
ALKIS_SF_URL = "https://geodienste.sachsen.de/aaa/public_alkis/sf/wfs"
|
ALKIS_SF_URL = "https://geodienste.sachsen.de/aaa/public_alkis/sf/wfs"
|
||||||
FLST_TYPENAME = "adv:AX_Flurstueck"
|
FLST_TYPENAME = "adv:AX_Flurstueck"
|
||||||
FLST_LAYER_NAME = "Flurstücke"
|
FLST_LAYER_NAME = "Flurstücke"
|
||||||
|
FELD_FLURSTUECKSKENNZEICHEN = "flurstueckskennzeichen"
|
||||||
|
|
||||||
|
|
||||||
def _check_existing_flurstueck_layer(tab_widget):
|
def _check_existing_flurstueck_layer(tab_widget):
|
||||||
@@ -74,6 +77,24 @@ def _check_existing_flurstueck_layer(tab_widget):
|
|||||||
return None, LoadStatus.NONE
|
return None, LoadStatus.NONE
|
||||||
|
|
||||||
|
|
||||||
|
def _vorhandene_kennzeichen(layer) -> set:
|
||||||
|
"""Liefert die ``flurstueckskennzeichen``-Werte, die ``layer`` bereits enthält.
|
||||||
|
|
||||||
|
Fehlt das Feld, wird eine leere Menge zurückgegeben (kein Abgleich möglich).
|
||||||
|
"""
|
||||||
|
kennzeichen: set = set()
|
||||||
|
if layer.fields().indexFromName(FELD_FLURSTUECKSKENNZEICHEN) < 0:
|
||||||
|
return kennzeichen
|
||||||
|
for feat in layer.getFeatures():
|
||||||
|
try:
|
||||||
|
kz = str(feat[FELD_FLURSTUECKSKENNZEICHEN] or "").strip()
|
||||||
|
except Exception:
|
||||||
|
kz = ""
|
||||||
|
if kz:
|
||||||
|
kennzeichen.add(kz)
|
||||||
|
return kennzeichen
|
||||||
|
|
||||||
|
|
||||||
def lade_flurstuecke_per_gemarkung(schluessel_liste: List[str]):
|
def lade_flurstuecke_per_gemarkung(schluessel_liste: List[str]):
|
||||||
"""Lädt Flurstücke für mehrere Gemarkungen, eine WFS-Anfrage pro Schlüssel.
|
"""Lädt Flurstücke für mehrere Gemarkungen, eine WFS-Anfrage pro Schlüssel.
|
||||||
|
|
||||||
@@ -152,6 +173,7 @@ def flurstueck_alkis(
|
|||||||
vorgabe_namen: Optional[List[str]] = None,
|
vorgabe_namen: Optional[List[str]] = None,
|
||||||
bbox=None,
|
bbox=None,
|
||||||
ohne_dialog: bool = False,
|
ohne_dialog: bool = False,
|
||||||
|
ohne_schluessel_abfrage: bool = False,
|
||||||
) -> Tuple[Optional[QgsVectorLayer], LoadStatus]:
|
) -> Tuple[Optional[QgsVectorLayer], LoadStatus]:
|
||||||
"""Lädt Flurstücke aus dem ALKIS-WFS anhand von Gemarkungsschlüsseln.
|
"""Lädt Flurstücke aus dem ALKIS-WFS anhand von Gemarkungsschlüsseln.
|
||||||
|
|
||||||
@@ -165,17 +187,27 @@ def flurstueck_alkis(
|
|||||||
Eltern-Widget für Dialoge.
|
Eltern-Widget für Dialoge.
|
||||||
vorgabe_schluessel : list of str, optional
|
vorgabe_schluessel : list of str, optional
|
||||||
Vorausgefüllte Gemarkungsnummern (4-stellig). Im Dialog als Standard
|
Vorausgefüllte Gemarkungsnummern (4-stellig). Im Dialog als Standard
|
||||||
angezeigt; bei ``ohne_dialog=True`` direkt verwendet.
|
angezeigt; bei ``ohne_dialog=True`` oder ``ohne_schluessel_abfrage=True``
|
||||||
|
direkt verwendet.
|
||||||
vorgabe_namen : list of str, optional
|
vorgabe_namen : list of str, optional
|
||||||
Menschenlesbare Gemarkungsbezeichnungen für den Dialog-Hinweistext.
|
Menschenlesbare Gemarkungsbezeichnungen für den Dialog-Hinweistext.
|
||||||
bbox :
|
bbox :
|
||||||
Nicht mehr verwendet (WFS unterstützt keinen BBox-Filter). Bleibt
|
Nicht mehr verwendet (WFS unterstützt keinen BBox-Filter). Bleibt
|
||||||
für Rückwärtskompatibilität in der Signatur erhalten.
|
für Rückwärtskompatibilität in der Signatur erhalten.
|
||||||
ohne_dialog : bool, optional
|
ohne_dialog : bool, optional
|
||||||
``True``: Überspringt die Gemarkungsschlüssel-Nutzerabfrage und verwendet
|
``True``: Überspringt sowohl die Gemarkungsschlüssel-Nutzerabfrage (wie
|
||||||
``vorgabe_schluessel`` direkt. Vorhandene Layer werden ohne Rückfrage
|
``ohne_schluessel_abfrage``) als auch die Rückfrage bei einem bereits
|
||||||
ersetzt. Gedacht für die automatische Pipeline
|
vorhandenen Layer – dieser wird dann immer ersetzt. Gedacht für die
|
||||||
(``verfahrensgebiet_alkis_komplett``). Standard: ``False``.
|
automatischen Pipelines (``verfahrensgebiet_alkis_komplett``,
|
||||||
|
``verfahrensgebiet_shape_komplett``). Standard: ``False``.
|
||||||
|
ohne_schluessel_abfrage : bool, optional
|
||||||
|
``True``: Überspringt nur die Gemarkungsschlüssel-Nutzerabfrage und
|
||||||
|
verwendet ``vorgabe_schluessel`` direkt; die Rückfrage bei einem
|
||||||
|
bereits vorhandenen Layer (Überschreiben/Anhängen/Abbrechen, inkl.
|
||||||
|
Dedup beim Anhängen) bleibt aktiv. Für Aufrufer, die die Schlüssel
|
||||||
|
bereits anderweitig ermittelt haben (z. B. aus einer Layer-Auswahl),
|
||||||
|
aber trotzdem interaktiv mit einem bestehenden Layer umgehen wollen.
|
||||||
|
Wirkungslos, wenn ``ohne_dialog=True`` gesetzt ist. Standard: ``False``.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
@@ -201,8 +233,8 @@ def flurstueck_alkis(
|
|||||||
append_target = existing
|
append_target = existing
|
||||||
|
|
||||||
# --- Schritt 2: Gemarkungsschlüssel bestimmen -------------------------
|
# --- Schritt 2: Gemarkungsschlüssel bestimmen -------------------------
|
||||||
if ohne_dialog:
|
if ohne_dialog or ohne_schluessel_abfrage:
|
||||||
# Pipeline-Modus: vorgabe_schluessel direkt verwenden, kein Dialog
|
# vorgabe_schluessel direkt verwenden, kein ask_text-Dialog
|
||||||
if not vorgabe_schluessel:
|
if not vorgabe_schluessel:
|
||||||
return None, LoadStatus.NONE
|
return None, LoadStatus.NONE
|
||||||
schluessel_liste = [s.strip() for s in vorgabe_schluessel if s.strip()]
|
schluessel_liste = [s.strip() for s in vorgabe_schluessel if s.strip()]
|
||||||
@@ -250,7 +282,22 @@ def flurstueck_alkis(
|
|||||||
|
|
||||||
# --- Anhängen an vorhandenen Layer ------------------------------------
|
# --- Anhängen an vorhandenen Layer ------------------------------------
|
||||||
if status == LoadStatus.APPEND and append_target is not None:
|
if status == LoadStatus.APPEND and append_target is not None:
|
||||||
append_target.dataProvider().addFeatures(list(layer.getFeatures()))
|
alle_feats = list(layer.getFeatures())
|
||||||
|
neue_feats = alle_feats
|
||||||
|
if layer.fields().indexFromName(FELD_FLURSTUECKSKENNZEICHEN) >= 0:
|
||||||
|
vorhandene = _vorhandene_kennzeichen(append_target)
|
||||||
|
neue_feats = [
|
||||||
|
f for f in alle_feats
|
||||||
|
if str(f[FELD_FLURSTUECKSKENNZEICHEN] or "").strip() not in vorhandene
|
||||||
|
]
|
||||||
|
uebersprungen = len(alle_feats) - len(neue_feats)
|
||||||
|
if uebersprungen:
|
||||||
|
_info(
|
||||||
|
"Flurstücke",
|
||||||
|
f"{uebersprungen} bereits vorhandene Flurstücke übersprungen.",
|
||||||
|
duration=3,
|
||||||
|
)
|
||||||
|
append_target.dataProvider().addFeatures(neue_feats)
|
||||||
append_target.updateExtents()
|
append_target.updateExtents()
|
||||||
append_target.triggerRepaint()
|
append_target.triggerRepaint()
|
||||||
return append_target, LoadStatus.APPEND
|
return append_target, LoadStatus.APPEND
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ from sn_basis.functions import QgsVectorLayer, QgsProject
|
|||||||
from sn_basis.functions import QMessageBox
|
from sn_basis.functions import QMessageBox
|
||||||
from sn_basis.functions.message_wrapper import info, warning
|
from sn_basis.functions.message_wrapper import info, warning
|
||||||
from sn_basis.functions.dialog_wrapper import create_progress_dialog
|
from sn_basis.functions.dialog_wrapper import create_progress_dialog
|
||||||
|
from sn_basis.functions.ly_style_wrapper import apply_style
|
||||||
|
|
||||||
ALKIS_SF_URL = "https://geodienste.sachsen.de/aaa/public_alkis/sf/wfs"
|
ALKIS_SF_URL = "https://geodienste.sachsen.de/aaa/public_alkis/sf/wfs"
|
||||||
PUNKTORT_TA_TYPENAME = "adv:AX_PunktortTA"
|
PUNKTORT_TA_TYPENAME = "adv:AX_PunktortTA"
|
||||||
@@ -1652,6 +1653,7 @@ def grenzpunkte_gemarkungsweise(
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
project.addMapLayer(joined_layer)
|
project.addMapLayer(joined_layer)
|
||||||
|
apply_style(joined_layer, "alkis_grenzpunkte.qml")
|
||||||
|
|
||||||
prog.set_value(prog_gesamt)
|
prog.set_value(prog_gesamt)
|
||||||
prog.close()
|
prog.close()
|
||||||
|
|||||||
@@ -261,12 +261,12 @@ def _baue_layer_aus_landkreis_auswahl(tab_widget, kombinationen: dict, crs: str,
|
|||||||
"""Auswahl + Bau für den Landkreis-Fallback.
|
"""Auswahl + Bau für den Landkreis-Fallback.
|
||||||
|
|
||||||
Zeigt :func:`~sn_verfahrensgebiet.functions.verfahrensgebiet_dialoge.ask_landkreis_objekte`
|
Zeigt :func:`~sn_verfahrensgebiet.functions.verfahrensgebiet_dialoge.ask_landkreis_objekte`
|
||||||
(Mehrfachauswahl inkl. "Alle auswählen" und "Nur laden"-Checkbox). Die
|
(Mehrfachauswahl inkl. "Alle auswählen"). Die ausgewählten Kombinationen
|
||||||
ausgewählten Kombinationen werden anhand der ersten 5 Zeichen von
|
werden anhand der ersten 5 Zeichen von ``bezeichnung`` (= die eigentliche
|
||||||
``bezeichnung`` (= die eigentliche VKZ) gruppiert; je Gruppe wird EIN
|
VKZ) gruppiert; je Gruppe wird EIN Feature erzeugt (Geometrien der
|
||||||
Feature erzeugt (Geometrien der Gruppe verschmolzen). Damit entsteht bei
|
Gruppe verschmolzen). Damit entsteht bei Auswahl mehrerer/aller Objekte
|
||||||
Auswahl mehrerer/aller Objekte eines Landkreises ein Layer mit mehreren
|
eines Landkreises ein Layer mit mehreren Features – einem je
|
||||||
Features – einem je tatsächlichem Verfahren, nicht ein Gesamt-Blob.
|
tatsächlichem Verfahren, nicht ein Gesamt-Blob.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
tab_widget: Parent-Widget für Dialoge und Meldungen
|
tab_widget: Parent-Widget für Dialoge und Meldungen
|
||||||
@@ -275,13 +275,12 @@ def _baue_layer_aus_landkreis_auswahl(tab_widget, kombinationen: dict, crs: str,
|
|||||||
status: Lade-Status aus Phase 1 (FIRST/RELOAD), wird durchgereicht
|
status: Lade-Status aus Phase 1 (FIRST/RELOAD), wird durchgereicht
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Tuple[Optional[QgsVectorLayer], LoadStatus, bool]:
|
Tuple[Optional[QgsVectorLayer], LoadStatus]: ``(layer, status)``.
|
||||||
``(layer, status, nur_laden)``.
|
|
||||||
"""
|
"""
|
||||||
key_list = sorted(kombinationen.keys())
|
key_list = sorted(kombinationen.keys())
|
||||||
selected_keys, nur_laden = ask_landkreis_objekte(tab_widget, key_list)
|
selected_keys = ask_landkreis_objekte(tab_widget, key_list)
|
||||||
if not selected_keys:
|
if not selected_keys:
|
||||||
return None, LoadStatus.NONE, False
|
return None, LoadStatus.NONE
|
||||||
|
|
||||||
# Nach VKZ (erste 5 Zeichen der bezeichnung) gruppieren
|
# Nach VKZ (erste 5 Zeichen der bezeichnung) gruppieren
|
||||||
vkz_gruppen: dict[str, list] = {}
|
vkz_gruppen: dict[str, list] = {}
|
||||||
@@ -322,12 +321,12 @@ def _baue_layer_aus_landkreis_auswahl(tab_widget, kombinationen: dict, crs: str,
|
|||||||
|
|
||||||
if not neue_features:
|
if not neue_features:
|
||||||
QMessageBox.critical(tab_widget, "Fehler", "Keine Geometrien zum Verschmelzen gefunden.")
|
QMessageBox.critical(tab_widget, "Fehler", "Keine Geometrien zum Verschmelzen gefunden.")
|
||||||
return None, LoadStatus.NONE, False
|
return None, LoadStatus.NONE
|
||||||
|
|
||||||
pr.addFeatures(neue_features)
|
pr.addFeatures(neue_features)
|
||||||
memory_layer.updateExtents()
|
memory_layer.updateExtents()
|
||||||
|
|
||||||
return memory_layer, status, nur_laden
|
return memory_layer, status
|
||||||
|
|
||||||
|
|
||||||
def verfahrensgebiet_alkis(tab_widget, skip_existing_check: bool = False):
|
def verfahrensgebiet_alkis(tab_widget, skip_existing_check: bool = False):
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ from sn_basis.functions.dialog_wrapper import (
|
|||||||
create_progress_dialog,
|
create_progress_dialog,
|
||||||
show_info_dialog,
|
show_info_dialog,
|
||||||
ask_detailpruefung_oder_vg_laden,
|
ask_detailpruefung_oder_vg_laden,
|
||||||
|
ask_yes_no,
|
||||||
)
|
)
|
||||||
from sn_basis.functions.landkreise import LANDKREISE, ALLE_LANDKREISE
|
from sn_basis.functions.landkreise import LANDKREISE, ALLE_LANDKREISE
|
||||||
from sn_basis.functions.ly_style_wrapper import apply_style
|
from sn_basis.functions.ly_style_wrapper import apply_style
|
||||||
@@ -273,9 +274,13 @@ def verfahrensgebiet_alkis_komplett(
|
|||||||
durchsuchen) und wird danach immer geschlossen – auch wenn anschließend
|
durchsuchen) und wird danach immer geschlossen – auch wenn anschließend
|
||||||
der BROR-Auswahldialog erscheint (kein Fortschrittsdialog läuft
|
der BROR-Auswahldialog erscheint (kein Fortschrittsdialog läuft
|
||||||
währenddessen parallel zum Auswahldialog).
|
währenddessen parallel zum Auswahldialog).
|
||||||
|
- **STOP** (Zwischenabfrage "Weiter?"): erscheint nach dem Laden/Übernehmen
|
||||||
|
des BROR-Objekts, bevor Dialog 2 startet. Bei "Nein" bricht der Ablauf
|
||||||
|
ab, das BROR-Objekt bleibt aber im Projekt (ersetzt die frühere
|
||||||
|
"Nur Objekte laden"-Option des Landkreis-Auswahldialogs).
|
||||||
- **Dialog 2** (eigentlicher Workflow, 6 Schritte): startet erst, nachdem
|
- **Dialog 2** (eigentlicher Workflow, 6 Schritte): startet erst, nachdem
|
||||||
das Verfahrensgebiet feststeht (direkt nach Dialog 1 bei eindeutigem
|
das Verfahrensgebiet feststeht und die Stop-Abfrage mit "Ja" bestätigt
|
||||||
Treffer/KEEP, oder erst nach Bestätigung des Auswahldialogs mit OK).
|
wurde.
|
||||||
|
|
||||||
Schrittfolge in Dialog 2:
|
Schrittfolge in Dialog 2:
|
||||||
|
|
||||||
@@ -351,8 +356,6 @@ def verfahrensgebiet_alkis_komplett(
|
|||||||
# Dialog 1 schließt hier immer – egal ob eine Auswahl folgt oder nicht.
|
# Dialog 1 schließt hier immer – egal ob eine Auswahl folgt oder nicht.
|
||||||
progress_suche.close()
|
progress_suche.close()
|
||||||
|
|
||||||
nur_laden = False
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if vorab_layer is not None or not kombinationen:
|
if vorab_layer is not None or not kombinationen:
|
||||||
# KEEP oder Fehler/Abbruch bereits in Phase 1 entschieden
|
# KEEP oder Fehler/Abbruch bereits in Phase 1 entschieden
|
||||||
@@ -364,7 +367,7 @@ def verfahrensgebiet_alkis_komplett(
|
|||||||
# Objekt(e) des Landkreises auswählen – kein eigener Fortschritts-
|
# Objekt(e) des Landkreises auswählen – kein eigener Fortschritts-
|
||||||
# dialog währenddessen, nur der Auswahldialog selbst.
|
# dialog währenddessen, nur der Auswahldialog selbst.
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
alkis_vg_layer, vg_status, nur_laden = _baue_layer_aus_landkreis_auswahl(
|
alkis_vg_layer, vg_status = _baue_layer_aus_landkreis_auswahl(
|
||||||
tab_widget, kombinationen, crs, vg_status
|
tab_widget, kombinationen, crs, vg_status
|
||||||
)
|
)
|
||||||
if vg_status == LoadStatus.NONE or not alkis_vg_layer:
|
if vg_status == LoadStatus.NONE or not alkis_vg_layer:
|
||||||
@@ -387,12 +390,21 @@ def verfahrensgebiet_alkis_komplett(
|
|||||||
project.addMapLayer(alkis_vg_layer)
|
project.addMapLayer(alkis_vg_layer)
|
||||||
bror_was_added_by_us = True
|
bror_was_added_by_us = True
|
||||||
# Style direkt nach dem Laden anwenden – unabhängig vom weiteren
|
# Style direkt nach dem Laden anwenden – unabhängig vom weiteren
|
||||||
# Ablauf, damit auch "Nur Objekte laden" den Style erhält.
|
# Ablauf, damit auch bei "Nein" auf die Stop-Abfrage der Style
|
||||||
|
# gesetzt ist.
|
||||||
apply_style(alkis_vg_layer, BROR_STYLE_QML)
|
apply_style(alkis_vg_layer, BROR_STYLE_QML)
|
||||||
|
|
||||||
if nur_laden:
|
# ------------------------------------------------------------------
|
||||||
# Nutzer hat "Nur laden" angehakt – kein Dialog 2, kein weiterer
|
# STOP: Zwischenabfrage nach dem Laden des BROR-Objekts, bevor mit
|
||||||
# Workflow (Gemarkung/Flurstücke/Vergleich).
|
# Gemarkung/Flurstücke/Flächenvergleich fortgefahren wird (ersetzt
|
||||||
|
# die frühere "Nur Objekte laden"-Option).
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
if not ask_yes_no(
|
||||||
|
"Verfahrensgebiet laden",
|
||||||
|
f"Layer '{alkis_vg_layer.name()}' wurde geladen. Weiter?",
|
||||||
|
default=True,
|
||||||
|
parent=tab_widget,
|
||||||
|
):
|
||||||
abgeschlossen = True
|
abgeschlossen = True
|
||||||
return alkis_vg_layer, None, None, vg_status
|
return alkis_vg_layer, None, None, vg_status
|
||||||
|
|
||||||
|
|||||||
@@ -101,15 +101,15 @@ def ask_bror_kombinationen(
|
|||||||
def ask_landkreis_objekte(
|
def ask_landkreis_objekte(
|
||||||
parent: Any,
|
parent: Any,
|
||||||
kombinationen: list[tuple[str, str]],
|
kombinationen: list[tuple[str, str]],
|
||||||
) -> tuple[list[tuple[str, str]], bool]:
|
) -> list[tuple[str, str]]:
|
||||||
"""Zeigt Dialog zur Auswahl eines, mehrerer oder aller BROR-Objekte eines
|
"""Zeigt Dialog zur Auswahl eines, mehrerer oder aller BROR-Objekte eines
|
||||||
Landkreises (Fallback, wenn keine Verfahrensnummer gesetzt ist).
|
Landkreises (Fallback, wenn keine Verfahrensnummer gesetzt ist).
|
||||||
|
|
||||||
Wie :func:`ask_bror_kombinationen`, zusätzlich mit einer "Alle
|
Wie :func:`ask_bror_kombinationen`, zusätzlich mit einer "Alle
|
||||||
auswählen"-Checkbox (da hier potenziell deutlich mehr Treffer als bei der
|
auswählen"-Checkbox (da hier potenziell deutlich mehr Treffer als bei der
|
||||||
VKZ-Suche auftreten) und einer "Nur laden"-Checkbox, mit der gesteuert
|
VKZ-Suche auftreten). Ob nach dem Laden der weitere Workflow
|
||||||
wird, ob nach dem Laden der weitere Workflow (Gemarkung/Flurstücke/
|
(Gemarkung/Flurstücke/Flächenvergleich) fortgesetzt wird, klärt eine
|
||||||
Flächenvergleich) fortgesetzt werden soll.
|
separate Stop-Abfrage nach dem Laden – nicht mehr dieser Dialog.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
@@ -120,16 +120,16 @@ def ask_landkreis_objekte(
|
|||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
tuple[list[tuple[str, str]], bool]
|
list[tuple[str, str]]
|
||||||
``(ausgewaehlte_kombinationen, nur_laden)``. ``([], False)`` bei
|
Die gewählten ``(adv_name, bezeichnung)``-Tupel. Leere Liste bei
|
||||||
Abbruch oder wenn nichts ausgewählt wurde.
|
Abbruch oder wenn nichts ausgewählt wurde.
|
||||||
"""
|
"""
|
||||||
if not kombinationen:
|
if not kombinationen:
|
||||||
return [], False
|
return []
|
||||||
|
|
||||||
if QT_VERSION == 0: # Mock-Modus
|
if QT_VERSION == 0: # Mock-Modus
|
||||||
print(f"Mock-Modus: ask_landkreis_objekte → {kombinationen[:1]}")
|
print(f"Mock-Modus: ask_landkreis_objekte → {kombinationen[:1]}")
|
||||||
return kombinationen[:1], False
|
return kombinationen[:1]
|
||||||
|
|
||||||
dialog = QDialog(parent)
|
dialog = QDialog(parent)
|
||||||
dialog.setWindowTitle("Verfahrensgebiete aus Landkreis laden")
|
dialog.setWindowTitle("Verfahrensgebiete aus Landkreis laden")
|
||||||
@@ -204,9 +204,6 @@ def ask_landkreis_objekte(
|
|||||||
mehrfachauswahl_hinweis = QLabel("<small>Mehrfachauswahl mit Strg + Umschalt</small>")
|
mehrfachauswahl_hinweis = QLabel("<small>Mehrfachauswahl mit Strg + Umschalt</small>")
|
||||||
layout.addWidget(mehrfachauswahl_hinweis)
|
layout.addWidget(mehrfachauswahl_hinweis)
|
||||||
|
|
||||||
nur_laden_checkbox = QCheckBox("Nur Objekte laden (ohne weitere Prüfungen)")
|
|
||||||
layout.addWidget(nur_laden_checkbox)
|
|
||||||
|
|
||||||
buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
|
buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
|
||||||
buttons.accepted.connect(dialog.accept)
|
buttons.accepted.connect(dialog.accept)
|
||||||
buttons.rejected.connect(dialog.reject)
|
buttons.rejected.connect(dialog.reject)
|
||||||
@@ -235,11 +232,11 @@ def ask_landkreis_objekte(
|
|||||||
dialog.resize(breite, dialog.sizeHint().height())
|
dialog.resize(breite, dialog.sizeHint().height())
|
||||||
|
|
||||||
if exec_dialog(dialog) != DialogAccepted:
|
if exec_dialog(dialog) != DialogAccepted:
|
||||||
return [], False
|
return []
|
||||||
|
|
||||||
ausgewaehlte_zeilen = sorted(set(item.row() for item in table.selectedItems()))
|
ausgewaehlte_zeilen = sorted(set(item.row() for item in table.selectedItems()))
|
||||||
ausgewaehlt = [(table.item(row, 1).text(), table.item(row, 0).text()) for row in ausgewaehlte_zeilen]
|
ausgewaehlt = [(table.item(row, 1).text(), table.item(row, 0).text()) for row in ausgewaehlte_zeilen]
|
||||||
return ausgewaehlt, nur_laden_checkbox.isChecked()
|
return ausgewaehlt
|
||||||
|
|
||||||
|
|
||||||
def ask_landkreis_auswahl(
|
def ask_landkreis_auswahl(
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ oder kein Ergebnis liefert, bricht den Workflow ab.
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
import zipfile
|
import zipfile
|
||||||
@@ -106,6 +107,57 @@ _GEBIETSTYP_LAYER_NAMEN = {
|
|||||||
# Interne Hilfsfunktionen
|
# Interne Hilfsfunktionen
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def _normalisiere_feldname(name: str) -> str:
|
||||||
|
"""Normalisiert einen Feldnamen für den toleranten Vergleich.
|
||||||
|
|
||||||
|
Entfernt alle Zeichen außer Buchstaben/Ziffern (z.B. Punkte, Leerzeichen,
|
||||||
|
Unterstriche) und wandelt in Kleinbuchstaben um. Hintergrund: manche
|
||||||
|
Shape-Exporte liefern den Feldnamen ``FBSchl`` mit einem angehängten
|
||||||
|
Punkt (``FBSchl.``) oder abweichender Groß-/Kleinschreibung, wodurch ein
|
||||||
|
exakter Namensvergleich das Feld fälschlich als fehlend meldet (#44).
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
name :
|
||||||
|
Roher Feldname.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
str
|
||||||
|
Normalisierter Feldname (nur Kleinbuchstaben/Ziffern).
|
||||||
|
"""
|
||||||
|
return re.sub(r"[^a-zA-Z0-9]", "", name).lower()
|
||||||
|
|
||||||
|
|
||||||
|
def _finde_fbschl_index(raw_layer) -> int:
|
||||||
|
"""Sucht den Feldindex von ``FBSchl`` tolerant gegenüber Abweichungen im
|
||||||
|
Namen (Groß-/Kleinschreibung, angehängte Sonderzeichen wie ein Punkt).
|
||||||
|
|
||||||
|
Versucht zuerst den exakten Namen; schlägt das fehl, wird über alle
|
||||||
|
Felder mit normalisiertem Namensvergleich gesucht (siehe
|
||||||
|
:func:`_normalisiere_feldname`).
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
raw_layer :
|
||||||
|
Dateibasierter Shapefile-Layer.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
int
|
||||||
|
Feldindex, oder ``-1`` wenn kein passendes Feld gefunden wurde.
|
||||||
|
"""
|
||||||
|
idx = raw_layer.fields().indexFromName(FBSCHL_FELD)
|
||||||
|
if idx >= 0:
|
||||||
|
return idx
|
||||||
|
|
||||||
|
ziel = _normalisiere_feldname(FBSCHL_FELD)
|
||||||
|
for feld_idx, feld in enumerate(raw_layer.fields()):
|
||||||
|
if _normalisiere_feldname(feld.name()) == ziel:
|
||||||
|
return feld_idx
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
def _ermittle_gebietstyp_aus_fbschl(raw_layer) -> Tuple[Optional[str], Optional[str]]:
|
def _ermittle_gebietstyp_aus_fbschl(raw_layer) -> Tuple[Optional[str], Optional[str]]:
|
||||||
"""Prüft das Feld ``FBSchl`` und ermittelt den Gebietstyp.
|
"""Prüft das Feld ``FBSchl`` und ermittelt den Gebietstyp.
|
||||||
|
|
||||||
@@ -113,6 +165,10 @@ def _ermittle_gebietstyp_aus_fbschl(raw_layer) -> Tuple[Optional[str], Optional[
|
|||||||
zurück, damit der Aufrufer Fehler mehrerer Dateien sammeln und am Ende
|
zurück, damit der Aufrufer Fehler mehrerer Dateien sammeln und am Ende
|
||||||
gemeinsam anzeigen kann.
|
gemeinsam anzeigen kann.
|
||||||
|
|
||||||
|
Die Feldsuche ist tolerant gegenüber Abweichungen im Namen (z.B. ein
|
||||||
|
angehängter Punkt ``FBSchl.`` in manchen Shape-Exporten, siehe #44) –
|
||||||
|
siehe :func:`_finde_fbschl_index`.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
raw_layer :
|
raw_layer :
|
||||||
@@ -127,7 +183,7 @@ def _ermittle_gebietstyp_aus_fbschl(raw_layer) -> Tuple[Optional[str], Optional[
|
|||||||
``fehlertext`` beschreibt die Ursache (fehlendes Feld oder
|
``fehlertext`` beschreibt die Ursache (fehlendes Feld oder
|
||||||
unbekannter Wert).
|
unbekannter Wert).
|
||||||
"""
|
"""
|
||||||
idx = raw_layer.fields().indexFromName(FBSCHL_FELD)
|
idx = _finde_fbschl_index(raw_layer)
|
||||||
if idx < 0:
|
if idx < 0:
|
||||||
return None, f"Feld '{FBSCHL_FELD}' fehlt (Shape entspricht nicht dem erwarteten Inhalt)."
|
return None, f"Feld '{FBSCHL_FELD}' fehlt (Shape entspricht nicht dem erwarteten Inhalt)."
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,913 @@
|
|||||||
|
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||||
|
<qgis autoRefreshMode="Disabled" autoRefreshTime="0" hasScaleBasedVisibilityFlag="0" labelsEnabled="0" layerType="Vector" maxScale="0" minScale="100000000" readOnly="0" simplifyAlgorithm="0" simplifyDrawingHints="0" simplifyDrawingTol="1" simplifyLocal="1" simplifyMaxScale="1" styleCategories="AllStyleCategories" symbologyReferenceScale="-1" version="4.2.0-Belém do Pará">
|
||||||
|
<flags>
|
||||||
|
<Identifiable>1</Identifiable>
|
||||||
|
<Removable>1</Removable>
|
||||||
|
<Searchable>1</Searchable>
|
||||||
|
<Private>0</Private>
|
||||||
|
</flags>
|
||||||
|
<temporal accumulate="0" durationField="" durationUnit="min" enabled="0" endExpression="" endField="" fixedDuration="0" limitMode="0" mode="0" startExpression="" startField="">
|
||||||
|
<fixedRange>
|
||||||
|
<start></start>
|
||||||
|
<end></end>
|
||||||
|
</fixedRange>
|
||||||
|
</temporal>
|
||||||
|
<elevation binding="Centroid" clamping="Terrain" customToleranceEnabled="0" extrusion="0" extrusionEnabled="0" respectLayerSymbol="1" showMarkerSymbolInSurfacePlots="0" symbology="Line" type="IndividualFeatures" zoffset="0" zscale="1">
|
||||||
|
<data-defined-properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data-defined-properties>
|
||||||
|
<profileLineSymbol>
|
||||||
|
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="" type="line">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleLine" enabled="1" id="{524b77c5-d547-434b-918a-eaa8d67032a3}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="align_dash_pattern" type="QString" value="0"/>
|
||||||
|
<Option name="capstyle" type="QString" value="square"/>
|
||||||
|
<Option name="customdash" type="QString" value="5;2"/>
|
||||||
|
<Option name="customdash_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="customdash_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="dash_pattern_offset" type="QString" value="0"/>
|
||||||
|
<Option name="dash_pattern_offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="dash_pattern_offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="draw_inside_polygon" type="QString" value="0"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="line_color" type="QString" value="152,125,183,255,rgb:0.5960785,0.4901961,0.7176471,1"/>
|
||||||
|
<Option name="line_style" type="QString" value="solid"/>
|
||||||
|
<Option name="line_width" type="QString" value="0.6"/>
|
||||||
|
<Option name="line_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="offset" type="QString" value="0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="ring_filter" type="QString" value="0"/>
|
||||||
|
<Option name="trim_distance_end" type="QString" value="0"/>
|
||||||
|
<Option name="trim_distance_end_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="trim_distance_end_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="trim_distance_start" type="QString" value="0"/>
|
||||||
|
<Option name="trim_distance_start_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="trim_distance_start_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="tweak_dash_pattern_on_corners" type="QString" value="0"/>
|
||||||
|
<Option name="use_custom_dash" type="QString" value="0"/>
|
||||||
|
<Option name="width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</profileLineSymbol>
|
||||||
|
<profileFillSymbol>
|
||||||
|
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="" type="fill">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleFill" enabled="1" id="{a950bd48-1020-4bd8-ba91-53a188c9d8c0}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="color" type="QString" value="152,125,183,255,rgb:0.5960785,0.4901961,0.7176471,1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="109,89,131,255,rgb:0.4257572,0.3501335,0.5125963,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0.2"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="style" type="QString" value="solid"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</profileFillSymbol>
|
||||||
|
<profileMarkerSymbol>
|
||||||
|
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="" type="marker">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" enabled="1" id="{1432e3c3-aaae-4f1c-8df7-441e77bdd112}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="152,125,183,255,rgb:0.5960785,0.4901961,0.7176471,1"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="diamond"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="109,89,131,255,rgb:0.4257572,0.3501335,0.5125963,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0.2"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="3"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</profileMarkerSymbol>
|
||||||
|
</elevation>
|
||||||
|
<renderer-v2 enableorderby="0" forceraster="0" referencescale="-1" symbollevels="0" type="RuleRenderer">
|
||||||
|
<rules key="{b5ed05de-e0db-4029-a532-cc0c11943124}">
|
||||||
|
<rule filter=" "gp_abmarkung_Marke" = '1000' " key="{ba76030e-eb1e-4a5a-b10c-b8614af46b1a}" label="Abgemarkt" symbol="0">
|
||||||
|
<rule filter=""gp_festgestellterGrenzpunkt" = 'true'" key="{0f910cf3-1e11-45f4-b4a5-5b8b11f4e2f3}" label="FGP" symbol="1"/>
|
||||||
|
</rule>
|
||||||
|
<rule filter=" "gp_abmarkung_Marke" IN ('9500')" key="{f530f073-c1a2-426e-9394-eb137d98b1fd}" label="Nicht abgemarkt" symbol="2">
|
||||||
|
<rule filter=""gp_festgestellterGrenzpunkt" = 'true'" key="{c1a0a382-cbf0-4981-b461-33c42c64701e}" label="FGP" symbol="3"/>
|
||||||
|
</rule>
|
||||||
|
<rule filter=" "gp_abmarkung_Marke" IN ('9600')" key="{f9d78633-b6a7-40df-88b4-d2d5bd51d1ab}" label="zeitweilig ausgesetzt" symbol="4">
|
||||||
|
<rule filter=""gp_festgestellterGrenzpunkt" = 'true'" key="{66a1f910-5127-4e2c-8c55-bb48f290be47}" label="FGP" symbol="5"/>
|
||||||
|
</rule>
|
||||||
|
</rules>
|
||||||
|
<symbols>
|
||||||
|
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="0" type="marker">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" enabled="1" id="{4b2b5770-c712-4a17-a7e7-e8d833a5ef55}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="255,255,255,255,hsv:0,0,1,1"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.1372549,0.1372549,0.1372549,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="1"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="6"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="1" type="marker">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" enabled="1" id="{e3e8ca93-babc-4c67-803f-73b091b1dcbf}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="255,255,255,0,hsv:0,0,1,0"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="outline_color" type="QString" value="227,26,28,255,rgb:0.8901961,0.1019608,0.1098039,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="1"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="8"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="2" type="marker">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" enabled="1" id="{3b684a01-3cd1-4ec2-a3b3-5dd097cac078}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="255,255,255,255,hsv:0,0,1,1"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.1372549,0.1372549,0.1372549,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="no"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="6"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
<layer class="SimpleMarker" enabled="1" id="{7cf47a18-2311-467c-835d-8a5ba1dcbbf9}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="0,0,0,255,hsv:0.99550002813339233,0.60656136274337769,0,1"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.1372549,0.1372549,0.1372549,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="3" type="marker">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" enabled="1" id="{e3e8ca93-babc-4c67-803f-73b091b1dcbf}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="255,255,255,0,hsv:0,0,1,0"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="outline_color" type="QString" value="227,26,28,255,rgb:0.8901961,0.1019608,0.1098039,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="1"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="8"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="4" type="marker">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" enabled="1" id="{3b684a01-3cd1-4ec2-a3b3-5dd097cac078}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="255,255,255,255,hsv:0,0,1,1"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.1372549,0.1372549,0.1372549,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="1"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="6"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
<layer class="SimpleMarker" enabled="1" id="{7cf47a18-2311-467c-835d-8a5ba1dcbbf9}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="0,0,0,255,hsv:0.99550002813339233,0.60656136274337769,0,1"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.1372549,0.1372549,0.1372549,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="5" type="marker">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" enabled="1" id="{e3e8ca93-babc-4c67-803f-73b091b1dcbf}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="255,255,255,0,hsv:0,0,1,0"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="outline_color" type="QString" value="227,26,28,255,rgb:0.8901961,0.1019608,0.1098039,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="1"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="8"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="Point"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</symbols>
|
||||||
|
<data-defined-properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data-defined-properties>
|
||||||
|
</renderer-v2>
|
||||||
|
<selection mode="Default">
|
||||||
|
<selectionColor invalid="1"/>
|
||||||
|
<selectionSymbol>
|
||||||
|
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="" type="marker">
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
<layer class="SimpleMarker" enabled="1" id="{4e7caead-e027-4f3e-a2ff-5a600d1c387c}" locked="0" pass="0">
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="angle" type="QString" value="0"/>
|
||||||
|
<Option name="cap_style" type="QString" value="square"/>
|
||||||
|
<Option name="color" type="QString" value="255,0,0,255,rgb:1,0,0,1"/>
|
||||||
|
<Option name="horizontal_anchor_point" type="QString" value="1"/>
|
||||||
|
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||||
|
<Option name="name" type="QString" value="circle"/>
|
||||||
|
<Option name="offset" type="QString" value="0,0"/>
|
||||||
|
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="offset_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.1372549,0.1372549,0.1372549,1"/>
|
||||||
|
<Option name="outline_style" type="QString" value="solid"/>
|
||||||
|
<Option name="outline_width" type="QString" value="0"/>
|
||||||
|
<Option name="outline_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="scale_method" type="QString" value="diameter"/>
|
||||||
|
<Option name="size" type="QString" value="2"/>
|
||||||
|
<Option name="size_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||||
|
<Option name="size_unit" type="QString" value="MM"/>
|
||||||
|
<Option name="vertical_anchor_point" type="QString" value="1"/>
|
||||||
|
</Option>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="name" type="QString" value=""/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option name="type" type="QString" value="collection"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</selectionSymbol>
|
||||||
|
</selection>
|
||||||
|
<customproperties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option name="dualview/previewExpressions" type="List">
|
||||||
|
<Option type="QString" value="COALESCE( "gml_id", '<NULL>' )"/>
|
||||||
|
</Option>
|
||||||
|
<Option name="embeddedWidgets/count" type="int" value="0"/>
|
||||||
|
<Option name="variableNames"/>
|
||||||
|
<Option name="variableValues"/>
|
||||||
|
</Option>
|
||||||
|
</customproperties>
|
||||||
|
<blendMode>0</blendMode>
|
||||||
|
<featureBlendMode>0</featureBlendMode>
|
||||||
|
<layerOpacity>1</layerOpacity>
|
||||||
|
<geometryOptions geometryPrecision="0" removeDuplicateNodes="0">
|
||||||
|
<activeChecks/>
|
||||||
|
<checkConfiguration/>
|
||||||
|
</geometryOptions>
|
||||||
|
<legend showLabelLegend="0" type="default-vector"/>
|
||||||
|
<referencedLayers/>
|
||||||
|
<referencingLayers/>
|
||||||
|
<fieldConfiguration>
|
||||||
|
<field configurationFlags="0" name="gml_id">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="identifier">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="lebenszeitintervall">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="modellart">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="anlass">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="zeigtAufExternes">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="istTeilVon">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="kartendarstellung">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="koordinatenstatus">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_gml_id">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_identifier">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_lebenszeitintervall">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_modellart">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_anlass">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_zeigtAufExternes">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_bestehtAus">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_punktkennung">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_abmarkung_Marke">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_festgestellterGrenzpunkt">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_inversZu_zeigtAuf">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
<field configurationFlags="0" name="gp_sonstigeEigenschaft">
|
||||||
|
<editWidget type="TextEdit">
|
||||||
|
<config>
|
||||||
|
<Option/>
|
||||||
|
</config>
|
||||||
|
</editWidget>
|
||||||
|
</field>
|
||||||
|
</fieldConfiguration>
|
||||||
|
<aliases>
|
||||||
|
<alias field="gml_id" index="0" name=""/>
|
||||||
|
<alias field="identifier" index="1" name=""/>
|
||||||
|
<alias field="lebenszeitintervall" index="2" name=""/>
|
||||||
|
<alias field="modellart" index="3" name=""/>
|
||||||
|
<alias field="anlass" index="4" name=""/>
|
||||||
|
<alias field="zeigtAufExternes" index="5" name=""/>
|
||||||
|
<alias field="istTeilVon" index="6" name=""/>
|
||||||
|
<alias field="kartendarstellung" index="7" name=""/>
|
||||||
|
<alias field="koordinatenstatus" index="8" name=""/>
|
||||||
|
<alias field="qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe" index="9" name=""/>
|
||||||
|
<alias field="gp_gml_id" index="10" name=""/>
|
||||||
|
<alias field="gp_identifier" index="11" name=""/>
|
||||||
|
<alias field="gp_lebenszeitintervall" index="12" name=""/>
|
||||||
|
<alias field="gp_modellart" index="13" name=""/>
|
||||||
|
<alias field="gp_anlass" index="14" name=""/>
|
||||||
|
<alias field="gp_zeigtAufExternes" index="15" name=""/>
|
||||||
|
<alias field="gp_bestehtAus" index="16" name=""/>
|
||||||
|
<alias field="gp_punktkennung" index="17" name=""/>
|
||||||
|
<alias field="gp_abmarkung_Marke" index="18" name=""/>
|
||||||
|
<alias field="gp_festgestellterGrenzpunkt" index="19" name=""/>
|
||||||
|
<alias field="gp_inversZu_zeigtAuf" index="20" name=""/>
|
||||||
|
<alias field="gp_sonstigeEigenschaft" index="21" name=""/>
|
||||||
|
</aliases>
|
||||||
|
<defaults>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gml_id"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="identifier"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="lebenszeitintervall"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="modellart"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="anlass"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="zeigtAufExternes"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="istTeilVon"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="kartendarstellung"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="koordinatenstatus"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_gml_id"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_identifier"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_lebenszeitintervall"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_modellart"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_anlass"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_zeigtAufExternes"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_bestehtAus"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_punktkennung"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_abmarkung_Marke"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_festgestellterGrenzpunkt"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_inversZu_zeigtAuf"/>
|
||||||
|
<default applyOnUpdate="0" expression="" field="gp_sonstigeEigenschaft"/>
|
||||||
|
</defaults>
|
||||||
|
<constraints>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gml_id" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="identifier" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="lebenszeitintervall" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="modellart" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="anlass" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="zeigtAufExternes" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="istTeilVon" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="kartendarstellung" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="koordinatenstatus" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_gml_id" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_identifier" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_lebenszeitintervall" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_modellart" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_anlass" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_zeigtAufExternes" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_bestehtAus" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_punktkennung" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_abmarkung_Marke" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_festgestellterGrenzpunkt" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_inversZu_zeigtAuf" notnull_strength="0" unique_strength="0"/>
|
||||||
|
<constraint constraints="0" exp_strength="0" field="gp_sonstigeEigenschaft" notnull_strength="0" unique_strength="0"/>
|
||||||
|
</constraints>
|
||||||
|
<constraintExpressions>
|
||||||
|
<constraint desc="" exp="" field="gml_id"/>
|
||||||
|
<constraint desc="" exp="" field="identifier"/>
|
||||||
|
<constraint desc="" exp="" field="lebenszeitintervall"/>
|
||||||
|
<constraint desc="" exp="" field="modellart"/>
|
||||||
|
<constraint desc="" exp="" field="anlass"/>
|
||||||
|
<constraint desc="" exp="" field="zeigtAufExternes"/>
|
||||||
|
<constraint desc="" exp="" field="istTeilVon"/>
|
||||||
|
<constraint desc="" exp="" field="kartendarstellung"/>
|
||||||
|
<constraint desc="" exp="" field="koordinatenstatus"/>
|
||||||
|
<constraint desc="" exp="" field="qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe"/>
|
||||||
|
<constraint desc="" exp="" field="gp_gml_id"/>
|
||||||
|
<constraint desc="" exp="" field="gp_identifier"/>
|
||||||
|
<constraint desc="" exp="" field="gp_lebenszeitintervall"/>
|
||||||
|
<constraint desc="" exp="" field="gp_modellart"/>
|
||||||
|
<constraint desc="" exp="" field="gp_anlass"/>
|
||||||
|
<constraint desc="" exp="" field="gp_zeigtAufExternes"/>
|
||||||
|
<constraint desc="" exp="" field="gp_bestehtAus"/>
|
||||||
|
<constraint desc="" exp="" field="gp_punktkennung"/>
|
||||||
|
<constraint desc="" exp="" field="gp_abmarkung_Marke"/>
|
||||||
|
<constraint desc="" exp="" field="gp_festgestellterGrenzpunkt"/>
|
||||||
|
<constraint desc="" exp="" field="gp_inversZu_zeigtAuf"/>
|
||||||
|
<constraint desc="" exp="" field="gp_sonstigeEigenschaft"/>
|
||||||
|
</constraintExpressions>
|
||||||
|
<expressionfields/>
|
||||||
|
<attributeactions>
|
||||||
|
<defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/>
|
||||||
|
</attributeactions>
|
||||||
|
<attributetableconfig actionWidgetStyle="dropDown" sortExpression="" sortOrder="0">
|
||||||
|
<columns>
|
||||||
|
<column hidden="0" name="gml_id" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="identifier" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="lebenszeitintervall" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="modellart" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="anlass" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="zeigtAufExternes" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="istTeilVon" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="kartendarstellung" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="koordinatenstatus" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_gml_id" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_identifier" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_lebenszeitintervall" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_modellart" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_anlass" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_zeigtAufExternes" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_bestehtAus" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_punktkennung" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_abmarkung_Marke" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_festgestellterGrenzpunkt" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_inversZu_zeigtAuf" type="field" width="-1"/>
|
||||||
|
<column hidden="0" name="gp_sonstigeEigenschaft" type="field" width="-1"/>
|
||||||
|
<column hidden="1" type="actions" width="-1"/>
|
||||||
|
</columns>
|
||||||
|
</attributetableconfig>
|
||||||
|
<conditionalstyles>
|
||||||
|
<rowstyles/>
|
||||||
|
<fieldstyles/>
|
||||||
|
</conditionalstyles>
|
||||||
|
<storedexpressions/>
|
||||||
|
<editform tolerant="1"></editform>
|
||||||
|
<editforminit/>
|
||||||
|
<editforminitcodesource>0</editforminitcodesource>
|
||||||
|
<editforminitfilepath></editforminitfilepath>
|
||||||
|
<editforminitcode><![CDATA[# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
QGIS-Formulare können eine Python-Funktion haben,, die aufgerufen wird, wenn sich das Formular öffnet
|
||||||
|
|
||||||
|
Diese Funktion kann verwendet werden um dem Formular Extralogik hinzuzufügen.
|
||||||
|
|
||||||
|
Der Name der Funktion wird im Feld "Python Init-Function" angegeben
|
||||||
|
Ein Beispiel folgt:
|
||||||
|
"""
|
||||||
|
from qgis.PyQt.QtWidgets import QWidget
|
||||||
|
|
||||||
|
def my_form_open(dialog, layer, feature):
|
||||||
|
geom = feature.geometry()
|
||||||
|
control = dialog.findChild(QWidget, "MyLineEdit")
|
||||||
|
]]></editforminitcode>
|
||||||
|
<featformsuppress>0</featformsuppress>
|
||||||
|
<editorlayout>generatedlayout</editorlayout>
|
||||||
|
<editable>
|
||||||
|
<field editable="1" name="anlass"/>
|
||||||
|
<field editable="1" name="gml_id"/>
|
||||||
|
<field editable="1" name="gp_abmarkung_Marke"/>
|
||||||
|
<field editable="1" name="gp_anlass"/>
|
||||||
|
<field editable="1" name="gp_bestehtAus"/>
|
||||||
|
<field editable="1" name="gp_festgestellterGrenzpunkt"/>
|
||||||
|
<field editable="1" name="gp_gml_id"/>
|
||||||
|
<field editable="1" name="gp_identifier"/>
|
||||||
|
<field editable="1" name="gp_inversZu_zeigtAuf"/>
|
||||||
|
<field editable="1" name="gp_lebenszeitintervall"/>
|
||||||
|
<field editable="1" name="gp_modellart"/>
|
||||||
|
<field editable="1" name="gp_punktkennung"/>
|
||||||
|
<field editable="1" name="gp_sonstigeEigenschaft"/>
|
||||||
|
<field editable="1" name="gp_zeigtAufExternes"/>
|
||||||
|
<field editable="1" name="identifier"/>
|
||||||
|
<field editable="1" name="istTeilVon"/>
|
||||||
|
<field editable="1" name="kartendarstellung"/>
|
||||||
|
<field editable="1" name="koordinatenstatus"/>
|
||||||
|
<field editable="1" name="lebenszeitintervall"/>
|
||||||
|
<field editable="1" name="modellart"/>
|
||||||
|
<field editable="1" name="qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe"/>
|
||||||
|
<field editable="1" name="zeigtAufExternes"/>
|
||||||
|
</editable>
|
||||||
|
<labelOnTop>
|
||||||
|
<field labelOnTop="0" name="anlass"/>
|
||||||
|
<field labelOnTop="0" name="gml_id"/>
|
||||||
|
<field labelOnTop="0" name="gp_abmarkung_Marke"/>
|
||||||
|
<field labelOnTop="0" name="gp_anlass"/>
|
||||||
|
<field labelOnTop="0" name="gp_bestehtAus"/>
|
||||||
|
<field labelOnTop="0" name="gp_festgestellterGrenzpunkt"/>
|
||||||
|
<field labelOnTop="0" name="gp_gml_id"/>
|
||||||
|
<field labelOnTop="0" name="gp_identifier"/>
|
||||||
|
<field labelOnTop="0" name="gp_inversZu_zeigtAuf"/>
|
||||||
|
<field labelOnTop="0" name="gp_lebenszeitintervall"/>
|
||||||
|
<field labelOnTop="0" name="gp_modellart"/>
|
||||||
|
<field labelOnTop="0" name="gp_punktkennung"/>
|
||||||
|
<field labelOnTop="0" name="gp_sonstigeEigenschaft"/>
|
||||||
|
<field labelOnTop="0" name="gp_zeigtAufExternes"/>
|
||||||
|
<field labelOnTop="0" name="identifier"/>
|
||||||
|
<field labelOnTop="0" name="istTeilVon"/>
|
||||||
|
<field labelOnTop="0" name="kartendarstellung"/>
|
||||||
|
<field labelOnTop="0" name="koordinatenstatus"/>
|
||||||
|
<field labelOnTop="0" name="lebenszeitintervall"/>
|
||||||
|
<field labelOnTop="0" name="modellart"/>
|
||||||
|
<field labelOnTop="0" name="qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe"/>
|
||||||
|
<field labelOnTop="0" name="zeigtAufExternes"/>
|
||||||
|
</labelOnTop>
|
||||||
|
<reuseLastValuePolicy>
|
||||||
|
<field name="anlass" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gml_id" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_abmarkung_Marke" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_anlass" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_bestehtAus" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_festgestellterGrenzpunkt" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_gml_id" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_identifier" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_inversZu_zeigtAuf" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_lebenszeitintervall" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_modellart" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_punktkennung" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_sonstigeEigenschaft" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="gp_zeigtAufExternes" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="identifier" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="istTeilVon" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="kartendarstellung" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="koordinatenstatus" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="lebenszeitintervall" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="modellart" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="qualitaetsangaben_ax_dqpunktort_genauigkeitsstufe" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
<field name="zeigtAufExternes" reuseLastValuePolicy="NotAllowed"/>
|
||||||
|
</reuseLastValuePolicy>
|
||||||
|
<dataDefinedFieldProperties/>
|
||||||
|
<widgets/>
|
||||||
|
<previewExpression>COALESCE( "gml_id", '<NULL>' )</previewExpression>
|
||||||
|
<mapTip enabled="1"></mapTip>
|
||||||
|
<layerGeometryType>0</layerGeometryType>
|
||||||
|
</qgis>
|
||||||
+221
-86
@@ -6,8 +6,11 @@ Getestet werden:
|
|||||||
- Nutzerabbruch bei ask_text → (None, LoadStatus.NONE)
|
- Nutzerabbruch bei ask_text → (None, LoadStatus.NONE)
|
||||||
- Ungültiger WFS-Layer → (None, LoadStatus.NONE)
|
- Ungültiger WFS-Layer → (None, LoadStatus.NONE)
|
||||||
- Erfolgreicher Ladevorgang → gültiger Layer + LoadStatus.FIRST
|
- Erfolgreicher Ladevorgang → gültiger Layer + LoadStatus.FIRST
|
||||||
- Bestehender Layer: Nutzer wählt "Neu laden" → LoadStatus.RELOAD
|
- Bestehender Layer, Drei-Knopf-Dialog: "Überschreiben" → LoadStatus.RELOAD,
|
||||||
- Bestehender Layer: Nutzer wählt "Behalten" → LoadStatus.KEEP
|
"Abbrechen" → (None, LoadStatus.NONE), "Anhängen" siehe
|
||||||
|
TestFlurstueckAlkisAnhaengenDedup
|
||||||
|
- vorgabe_schluessel/vorgabe_namen füllen den Eingabedialog vor
|
||||||
|
- ohne_schluessel_abfrage=True überspringt die ask_text-Abfrage
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
@@ -30,7 +33,12 @@ if "qgis" not in sys.modules:
|
|||||||
sys.modules["qgis.core"] = qgis_core
|
sys.modules["qgis.core"] = qgis_core
|
||||||
sys.modules["qgis.utils"] = qgis_utils
|
sys.modules["qgis.utils"] = qgis_utils
|
||||||
|
|
||||||
from sn_verfahrensgebiet.functions.flurstueck_alkis import flurstueck_alkis, FLST_LAYER_NAME
|
from sn_verfahrensgebiet.functions.flurstueck_alkis import (
|
||||||
|
flurstueck_alkis,
|
||||||
|
lade_flurstuecke_per_gemarkung,
|
||||||
|
FLST_LAYER_NAME,
|
||||||
|
FELD_FLURSTUECKSKENNZEICHEN,
|
||||||
|
)
|
||||||
from sn_verfahrensgebiet.functions.verfahrensgebiet_alkis import LoadStatus
|
from sn_verfahrensgebiet.functions.verfahrensgebiet_alkis import LoadStatus
|
||||||
|
|
||||||
|
|
||||||
@@ -49,8 +57,8 @@ class _DummyLayer:
|
|||||||
def id(self):
|
def id(self):
|
||||||
return self._id
|
return self._id
|
||||||
|
|
||||||
def extent(self):
|
def featureCount(self):
|
||||||
return object()
|
return 1
|
||||||
|
|
||||||
|
|
||||||
class _DummyProject:
|
class _DummyProject:
|
||||||
@@ -78,7 +86,7 @@ class TestFlurstueckAlkis(unittest.TestCase):
|
|||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
def test_user_cancel_returns_none(self, mock_ask_text, mock_project, mock_msgbox):
|
def test_user_cancel_returns_none(self, mock_ask_text, mock_project, mock_msgbox):
|
||||||
"""ask_text → ok=False, text="" → (None, NONE)."""
|
"""Prüft, dass ein Abbruch im Eingabedialog (ok=False) (None, LoadStatus.NONE) liefert."""
|
||||||
mock_ask_text.return_value = ("", False)
|
mock_ask_text.return_value = ("", False)
|
||||||
mock_project.return_value = _DummyProject()
|
mock_project.return_value = _DummyProject()
|
||||||
|
|
||||||
@@ -91,7 +99,7 @@ class TestFlurstueckAlkis(unittest.TestCase):
|
|||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
def test_empty_text_after_confirmation_returns_none(self, mock_ask_text, mock_project, mock_msgbox):
|
def test_empty_text_after_confirmation_returns_none(self, mock_ask_text, mock_project, mock_msgbox):
|
||||||
"""ask_text → ok=True, aber Text leer → (None, NONE)."""
|
"""Prüft, dass ein bestätigter, aber leerer Eingabetext ebenfalls (None, LoadStatus.NONE) liefert."""
|
||||||
mock_ask_text.return_value = (" ", True)
|
mock_ask_text.return_value = (" ", True)
|
||||||
mock_project.return_value = _DummyProject()
|
mock_project.return_value = _DummyProject()
|
||||||
|
|
||||||
@@ -110,7 +118,7 @@ class TestFlurstueckAlkis(unittest.TestCase):
|
|||||||
def test_invalid_wfs_layer_returns_none(
|
def test_invalid_wfs_layer_returns_none(
|
||||||
self, mock_ask_text, mock_project, mock_wfs_layer_cls, mock_msgbox
|
self, mock_ask_text, mock_project, mock_wfs_layer_cls, mock_msgbox
|
||||||
):
|
):
|
||||||
"""WFS-Layer nicht valide → (None, NONE)."""
|
"""Prüft, dass ein ungültiger WFS-Layer (None, LoadStatus.NONE) liefert."""
|
||||||
mock_ask_text.return_value = ("1234", True)
|
mock_ask_text.return_value = ("1234", True)
|
||||||
mock_project.return_value = _DummyProject()
|
mock_project.return_value = _DummyProject()
|
||||||
mock_wfs_layer_cls.return_value = _DummyLayer(valid=False)
|
mock_wfs_layer_cls.return_value = _DummyLayer(valid=False)
|
||||||
@@ -123,67 +131,64 @@ class TestFlurstueckAlkis(unittest.TestCase):
|
|||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
# 3. Erfolgreicher Erstladevorgang #
|
# 3. Erfolgreicher Erstladevorgang #
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.lade_flurstuecke_per_gemarkung")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
def test_success_returns_layer_and_first_status(
|
def test_success_returns_layer_and_first_status(
|
||||||
self, mock_ask_text, mock_project, mock_wfs_layer_cls
|
self, mock_ask_text, mock_project, mock_lade
|
||||||
):
|
):
|
||||||
"""Kein bestehender Layer, WFS valide → (layer, FIRST)."""
|
"""Prüft, dass ohne bestehenden Layer der von lade_flurstuecke_per_gemarkung gelieferte Layer mit LoadStatus.FIRST zurückgegeben wird."""
|
||||||
mock_ask_text.return_value = ("1234, 5678", True)
|
mock_ask_text.return_value = ("1234, 5678", True)
|
||||||
mock_project.return_value = _DummyProject()
|
mock_project.return_value = _DummyProject()
|
||||||
valid_layer = _DummyLayer(valid=True, layer_id="wfs_ok")
|
valid_layer = _DummyLayer(valid=True, layer_id="wfs_ok")
|
||||||
mock_wfs_layer_cls.return_value = valid_layer
|
mock_lade.return_value = valid_layer
|
||||||
|
|
||||||
layer, status = flurstueck_alkis(None)
|
layer, status = flurstueck_alkis(None)
|
||||||
|
|
||||||
self.assertIs(layer, valid_layer)
|
self.assertIs(layer, valid_layer)
|
||||||
self.assertEqual(status, LoadStatus.FIRST)
|
self.assertEqual(status, LoadStatus.FIRST)
|
||||||
|
mock_lade.assert_called_once_with(["1234", "5678"])
|
||||||
|
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
def test_sql_filter_contains_all_schluessel(self, mock_wfs_layer_cls):
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
"""Prüft, dass lade_flurstuecke_per_gemarkung für jeden Gemarkungsschlüssel eine eigene WFS-Anfrage mit dessen Schlüssel stellt."""
|
||||||
def test_sql_filter_contains_all_schluessel(
|
# Ungültig genügt: nur die aufgebaute URI je Aufruf wird geprüft, das
|
||||||
self, mock_ask_text, mock_project, mock_wfs_layer_cls
|
# tatsächliche Zusammenführen der Features ist nicht Teil dieses Tests.
|
||||||
):
|
mock_wfs_layer_cls.return_value = _DummyLayer(valid=False)
|
||||||
"""Der WFS-URI enthält alle eingegebenen Gemarkungsschlüssel."""
|
|
||||||
mock_ask_text.return_value = ("1111, 2222, 3333", True)
|
|
||||||
mock_project.return_value = _DummyProject()
|
|
||||||
mock_wfs_layer_cls.return_value = _DummyLayer(valid=True)
|
|
||||||
|
|
||||||
flurstueck_alkis(None)
|
lade_flurstuecke_per_gemarkung(["1111", "2222", "3333"])
|
||||||
|
|
||||||
# Erster Positionsarg von QgsVectorLayer ist der URI-String
|
uris = [call.args[0] for call in mock_wfs_layer_cls.call_args_list]
|
||||||
call_args = mock_wfs_layer_cls.call_args
|
self.assertEqual(len(uris), 3)
|
||||||
uri_str = call_args[0][0] if call_args[0] else call_args[1].get("path", "")
|
self.assertIn("1111", uris[0])
|
||||||
self.assertIn("1111", uri_str)
|
self.assertIn("2222", uris[1])
|
||||||
self.assertIn("2222", uri_str)
|
self.assertIn("3333", uris[2])
|
||||||
self.assertIn("3333", uri_str)
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
# 4. Bestehender Layer – Nutzer wählt "Neu laden" #
|
# 4. Bestehender Layer – Nutzer klickt "Überschreiben" #
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.lade_flurstuecke_per_gemarkung")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QMessageBox")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QMessageBox")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
def test_existing_layer_reload_yes(
|
def test_existing_layer_reload_yes(
|
||||||
self, mock_ask_text, mock_project, mock_msgbox_cls, mock_wfs_layer_cls
|
self, mock_ask_text, mock_project, mock_msgbox_cls, mock_lade
|
||||||
):
|
):
|
||||||
"""Bestehender Layer + Nutzer: 'Ja, neu laden' → LoadStatus.RELOAD."""
|
"""Prüft, dass bei bestehendem Layer und Klick auf 'Überschreiben' der alte Layer entfernt und LoadStatus.RELOAD geliefert wird."""
|
||||||
existing = _DummyLayer(valid=True, layer_id="old_flst")
|
existing = _DummyLayer(valid=True, layer_id="old_flst")
|
||||||
project = _DummyProject(named_layers=[existing])
|
project = _DummyProject(named_layers=[existing])
|
||||||
mock_ask_text.return_value = ("1234", True)
|
mock_ask_text.return_value = ("1234", True)
|
||||||
mock_project.return_value = project
|
mock_project.return_value = project
|
||||||
|
|
||||||
# StandardButton als int, damit | Operator funktioniert
|
# Drei-Knopf-Dialog: addButton() liefert je Aufruf einen eigenen
|
||||||
mock_msgbox_cls.StandardButton.Yes = 0x4000
|
# Sentinel, clickedButton() simuliert den Klick auf "Überschreiben".
|
||||||
mock_msgbox_cls.StandardButton.No = 0x10000
|
btn_ueberschreiben, btn_anhaengen, btn_abbrechen = object(), object(), object()
|
||||||
# QMessageBox.question → Yes
|
msg_instance = mock_msgbox_cls.return_value
|
||||||
mock_msgbox_cls.question.return_value = 0x4000
|
msg_instance.addButton.side_effect = [btn_ueberschreiben, btn_anhaengen, btn_abbrechen]
|
||||||
|
msg_instance.clickedButton.return_value = btn_ueberschreiben
|
||||||
|
|
||||||
new_layer = _DummyLayer(valid=True, layer_id="new_flst")
|
new_layer = _DummyLayer(valid=True, layer_id="new_flst")
|
||||||
mock_wfs_layer_cls.return_value = new_layer
|
mock_lade.return_value = new_layer
|
||||||
|
|
||||||
layer, status = flurstueck_alkis(None)
|
layer, status = flurstueck_alkis(None)
|
||||||
|
|
||||||
@@ -192,46 +197,46 @@ class TestFlurstueckAlkis(unittest.TestCase):
|
|||||||
self.assertEqual(status, LoadStatus.RELOAD)
|
self.assertEqual(status, LoadStatus.RELOAD)
|
||||||
|
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
# 5. Bestehender Layer – Nutzer wählt "Behalten" #
|
# 5. Bestehender Layer – Nutzer klickt "Abbrechen" #
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QMessageBox")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QMessageBox")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
def test_existing_layer_keep_no(
|
def test_existing_layer_abbrechen_returns_none(
|
||||||
self, mock_ask_text, mock_project, mock_msgbox_cls
|
self, mock_ask_text, mock_project, mock_msgbox_cls
|
||||||
):
|
):
|
||||||
"""Bestehender Layer + Nutzer: 'Nein, behalten' → LoadStatus.KEEP."""
|
"""Prüft, dass bei bestehendem Layer und Klick auf 'Abbrechen' nichts verändert wird und (None, LoadStatus.NONE) geliefert wird."""
|
||||||
existing = _DummyLayer(valid=True, layer_id="keep_flst")
|
existing = _DummyLayer(valid=True, layer_id="keep_flst")
|
||||||
project = _DummyProject(named_layers=[existing])
|
project = _DummyProject(named_layers=[existing])
|
||||||
mock_ask_text.return_value = ("1234", True)
|
mock_ask_text.return_value = ("1234", True)
|
||||||
mock_project.return_value = project
|
mock_project.return_value = project
|
||||||
|
|
||||||
# StandardButton als int, damit | Operator funktioniert
|
btn_ueberschreiben, btn_anhaengen, btn_abbrechen = object(), object(), object()
|
||||||
mock_msgbox_cls.StandardButton.Yes = 0x4000
|
msg_instance = mock_msgbox_cls.return_value
|
||||||
mock_msgbox_cls.StandardButton.No = 0x10000
|
msg_instance.addButton.side_effect = [btn_ueberschreiben, btn_anhaengen, btn_abbrechen]
|
||||||
# QMessageBox.question → No
|
msg_instance.clickedButton.return_value = btn_abbrechen
|
||||||
mock_msgbox_cls.question.return_value = 0x10000
|
|
||||||
|
|
||||||
layer, status = flurstueck_alkis(None)
|
layer, status = flurstueck_alkis(None)
|
||||||
|
|
||||||
self.assertIs(layer, existing)
|
self.assertIsNone(layer)
|
||||||
self.assertEqual(status, LoadStatus.KEEP)
|
self.assertEqual(status, LoadStatus.NONE)
|
||||||
self.assertEqual(project.removed, []) # nichts gelöscht
|
self.assertEqual(project.removed, []) # nichts gelöscht
|
||||||
|
mock_ask_text.assert_not_called() # Abbruch schon vor der Schlüsselabfrage
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
# 6. vorgabe_schluessel füllt ask_text-Default vor #
|
# 6. vorgabe_schluessel füllt ask_text-Default vor #
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.lade_flurstuecke_per_gemarkung")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
def test_vorgabe_schluessel_prefills_default_text(
|
def test_vorgabe_schluessel_prefills_default_text(
|
||||||
self, mock_ask_text, mock_project, mock_wfs_layer_cls
|
self, mock_ask_text, mock_project, mock_lade
|
||||||
):
|
):
|
||||||
"""vorgabe_schluessel=['1234','5678'] → ask_text erhält '1234, 5678' als default_text."""
|
"""Prüft, dass vorgabe_schluessel als vorbelegter default_text im Eingabedialog erscheint."""
|
||||||
mock_ask_text.return_value = ("1234, 5678", True)
|
mock_ask_text.return_value = ("1234, 5678", True)
|
||||||
mock_project.return_value = _DummyProject()
|
mock_project.return_value = _DummyProject()
|
||||||
mock_wfs_layer_cls.return_value = _DummyLayer(valid=True)
|
mock_lade.return_value = _DummyLayer(valid=True)
|
||||||
|
|
||||||
flurstueck_alkis(None, vorgabe_schluessel=["1234", "5678"])
|
flurstueck_alkis(None, vorgabe_schluessel=["1234", "5678"])
|
||||||
|
|
||||||
@@ -245,16 +250,16 @@ class TestFlurstueckAlkis(unittest.TestCase):
|
|||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
# 7. vorgabe_namen erscheint im Label-Text #
|
# 7. vorgabe_namen erscheint im Label-Text #
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.lade_flurstuecke_per_gemarkung")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
def test_vorgabe_namen_appears_in_label(
|
def test_vorgabe_namen_appears_in_label(
|
||||||
self, mock_ask_text, mock_project, mock_wfs_layer_cls
|
self, mock_ask_text, mock_project, mock_lade
|
||||||
):
|
):
|
||||||
"""vorgabe_namen=['Musterstadt'] → ask_text-label enthält den Namen."""
|
"""Prüft, dass vorgabe_namen im Beschriftungstext des Eingabedialogs erscheint."""
|
||||||
mock_ask_text.return_value = ("9999", True)
|
mock_ask_text.return_value = ("9999", True)
|
||||||
mock_project.return_value = _DummyProject()
|
mock_project.return_value = _DummyProject()
|
||||||
mock_wfs_layer_cls.return_value = _DummyLayer(valid=True)
|
mock_lade.return_value = _DummyLayer(valid=True)
|
||||||
|
|
||||||
flurstueck_alkis(None, vorgabe_namen=["Musterstadt"])
|
flurstueck_alkis(None, vorgabe_namen=["Musterstadt"])
|
||||||
|
|
||||||
@@ -264,49 +269,179 @@ class TestFlurstueckAlkis(unittest.TestCase):
|
|||||||
self.assertIn("Musterstadt", label_arg)
|
self.assertIn("Musterstadt", label_arg)
|
||||||
|
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
# 8. bbox wird in WFS-URI eingebettet #
|
# 8. Rückwärtskompatibilität: alle neuen Params optional #
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.lade_flurstuecke_per_gemarkung")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
|
||||||
def test_bbox_embedded_in_wfs_uri(
|
|
||||||
self, mock_ask_text, mock_project, mock_wfs_layer_cls
|
|
||||||
):
|
|
||||||
"""bbox-Parameter → WFS-URI enthält 'bbox=' Substring."""
|
|
||||||
mock_ask_text.return_value = ("1234", True)
|
|
||||||
mock_project.return_value = _DummyProject()
|
|
||||||
mock_wfs_layer_cls.return_value = _DummyLayer(valid=True)
|
|
||||||
|
|
||||||
class _Rect:
|
|
||||||
def xMinimum(self): return 414000.0
|
|
||||||
def yMinimum(self): return 5657000.0
|
|
||||||
def xMaximum(self): return 415000.0
|
|
||||||
def yMaximum(self): return 5658000.0
|
|
||||||
|
|
||||||
flurstueck_alkis(None, bbox=_Rect())
|
|
||||||
|
|
||||||
uri_str = mock_wfs_layer_cls.call_args[0][0]
|
|
||||||
self.assertIn("bbox=", uri_str.lower())
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------ #
|
|
||||||
# 9. Rückwärtskompatibilität: alle neuen Params optional #
|
|
||||||
# ------------------------------------------------------------------ #
|
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsVectorLayer")
|
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||||||
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
def test_backwards_compatible_no_new_params(
|
def test_backwards_compatible_no_new_params(
|
||||||
self, mock_ask_text, mock_project, mock_wfs_layer_cls
|
self, mock_ask_text, mock_project, mock_lade
|
||||||
):
|
):
|
||||||
"""flurstueck_alkis(tab) ohne neue Parameter → kein Fehler."""
|
"""Prüft, dass flurstueck_alkis() ohne die neuen optionalen Parameter weiterhin fehlerfrei einen Layer mit LoadStatus.FIRST liefert."""
|
||||||
mock_ask_text.return_value = ("0000", True)
|
mock_ask_text.return_value = ("0000", True)
|
||||||
mock_project.return_value = _DummyProject()
|
mock_project.return_value = _DummyProject()
|
||||||
mock_wfs_layer_cls.return_value = _DummyLayer(valid=True)
|
mock_lade.return_value = _DummyLayer(valid=True)
|
||||||
|
|
||||||
layer, status = flurstueck_alkis(None)
|
layer, status = flurstueck_alkis(None)
|
||||||
|
|
||||||
self.assertIsNotNone(layer)
|
self.assertIsNotNone(layer)
|
||||||
self.assertEqual(status, LoadStatus.FIRST)
|
self.assertEqual(status, LoadStatus.FIRST)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------ #
|
||||||
|
# 9. ohne_schluessel_abfrage: vorgabe_schluessel direkt, kein ask_text (#47)
|
||||||
|
# ------------------------------------------------------------------ #
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.lade_flurstuecke_per_gemarkung")
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.QgsProject.instance")
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
|
def test_ohne_schluessel_abfrage_ueberspringt_ask_text(
|
||||||
|
self, mock_ask_text, mock_project, mock_lade
|
||||||
|
):
|
||||||
|
"""Prüft, dass ohne_schluessel_abfrage=True vorgabe_schluessel direkt verwendet und ask_text nicht aufgerufen wird."""
|
||||||
|
mock_project.return_value = _DummyProject()
|
||||||
|
geladen = _DummyFlstLayer([_DummyFlstFeature("110001_0001__00001")])
|
||||||
|
mock_lade.return_value = geladen
|
||||||
|
|
||||||
|
layer, status = flurstueck_alkis(
|
||||||
|
None, vorgabe_schluessel=["1234", "5678"], ohne_schluessel_abfrage=True
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_ask_text.assert_not_called()
|
||||||
|
self.assertIs(layer, geladen)
|
||||||
|
self.assertEqual(status, LoadStatus.FIRST)
|
||||||
|
mock_lade.assert_called_once_with(["1234", "5678"])
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Dummies für den Anhängen-Deduplizierungstest (#28)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class _DummyFlstFeature:
|
||||||
|
def __init__(self, kennzeichen):
|
||||||
|
self._kennzeichen = kennzeichen
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
if key == FELD_FLURSTUECKSKENNZEICHEN:
|
||||||
|
return self._kennzeichen
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class _DummyFlstFields:
|
||||||
|
def __init__(self, hat_kennzeichen_feld: bool):
|
||||||
|
self._hat_feld = hat_kennzeichen_feld
|
||||||
|
|
||||||
|
def indexFromName(self, name):
|
||||||
|
if name == FELD_FLURSTUECKSKENNZEICHEN and self._hat_feld:
|
||||||
|
return 0
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
|
class _DummyFlstLayer:
|
||||||
|
"""Flurstück-Layer-Dummy mit Feature-Liste und aufzeichnendem ``dataProvider``."""
|
||||||
|
|
||||||
|
def __init__(self, features, hat_kennzeichen_feld: bool = True):
|
||||||
|
self._features = list(features)
|
||||||
|
self._hat_feld = hat_kennzeichen_feld
|
||||||
|
self.added = None
|
||||||
|
|
||||||
|
def getFeatures(self):
|
||||||
|
return list(self._features)
|
||||||
|
|
||||||
|
def fields(self):
|
||||||
|
return _DummyFlstFields(self._hat_feld)
|
||||||
|
|
||||||
|
def dataProvider(self):
|
||||||
|
layer = self
|
||||||
|
|
||||||
|
class _Provider:
|
||||||
|
def addFeatures(self, feats):
|
||||||
|
layer.added = list(feats)
|
||||||
|
layer._features.extend(feats)
|
||||||
|
return True
|
||||||
|
|
||||||
|
return _Provider()
|
||||||
|
|
||||||
|
def updateExtents(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def triggerRepaint(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def isValid(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def featureCount(self):
|
||||||
|
return len(self._features)
|
||||||
|
|
||||||
|
|
||||||
|
class TestFlurstueckAlkisAnhaengenDedup(unittest.TestCase):
|
||||||
|
"""Anhängen an einen bestehenden Flurstück-Layer (Issue #28)."""
|
||||||
|
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.lade_flurstuecke_per_gemarkung")
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis._check_existing_flurstueck_layer")
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
|
def test_append_ueberspringt_bereits_vorhandene_flurstuecke(
|
||||||
|
self, mock_ask_text, mock_check, mock_lade
|
||||||
|
):
|
||||||
|
"""Prüft, dass beim Anhängen bereits vorhandene flurstueckskennzeichen nicht erneut hinzugefügt werden."""
|
||||||
|
mock_ask_text.return_value = ("0001, 0002", True)
|
||||||
|
bestehend = _DummyFlstLayer([_DummyFlstFeature("110001_0001__00001")])
|
||||||
|
neu_geladen = _DummyFlstLayer([
|
||||||
|
_DummyFlstFeature("110001_0001__00001"), # bereits im Layer vorhanden
|
||||||
|
_DummyFlstFeature("110001_0002__00007"), # noch nicht vorhanden
|
||||||
|
])
|
||||||
|
mock_check.return_value = (bestehend, LoadStatus.APPEND)
|
||||||
|
mock_lade.return_value = neu_geladen
|
||||||
|
|
||||||
|
layer, status = flurstueck_alkis(None)
|
||||||
|
|
||||||
|
self.assertEqual(status, LoadStatus.APPEND)
|
||||||
|
self.assertIs(layer, bestehend)
|
||||||
|
self.assertEqual(len(bestehend.added), 1)
|
||||||
|
self.assertEqual(bestehend.added[0][FELD_FLURSTUECKSKENNZEICHEN], "110001_0002__00007")
|
||||||
|
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.lade_flurstuecke_per_gemarkung")
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis._check_existing_flurstueck_layer")
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
|
def test_append_ohne_kennzeichen_feld_haengt_alles_an(
|
||||||
|
self, mock_ask_text, mock_check, mock_lade
|
||||||
|
):
|
||||||
|
"""Prüft, dass ohne flurstueckskennzeichen-Feld weiterhin alle Features angehängt werden (Rückfallverhalten)."""
|
||||||
|
mock_ask_text.return_value = ("0001", True)
|
||||||
|
bestehend = _DummyFlstLayer([_DummyFlstFeature("110001_0001__00001")], hat_kennzeichen_feld=False)
|
||||||
|
neu_geladen = _DummyFlstLayer(
|
||||||
|
[_DummyFlstFeature("110001_0001__00001"), _DummyFlstFeature("110001_0002__00007")],
|
||||||
|
hat_kennzeichen_feld=False,
|
||||||
|
)
|
||||||
|
mock_check.return_value = (bestehend, LoadStatus.APPEND)
|
||||||
|
mock_lade.return_value = neu_geladen
|
||||||
|
|
||||||
|
layer, status = flurstueck_alkis(None)
|
||||||
|
|
||||||
|
self.assertEqual(status, LoadStatus.APPEND)
|
||||||
|
self.assertEqual(len(bestehend.added), 2)
|
||||||
|
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.lade_flurstuecke_per_gemarkung")
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis._check_existing_flurstueck_layer")
|
||||||
|
@patch("sn_verfahrensgebiet.functions.flurstueck_alkis.ask_text")
|
||||||
|
def test_ohne_schluessel_abfrage_append_dedup(self, mock_ask_text, mock_check, mock_lade):
|
||||||
|
"""ohne_schluessel_abfrage=True: Anhängen dedupliziert trotzdem, ohne nach Schlüsseln zu fragen (#47)."""
|
||||||
|
bestehend = _DummyFlstLayer([_DummyFlstFeature("110001_0001__00001")])
|
||||||
|
neu_geladen = _DummyFlstLayer([
|
||||||
|
_DummyFlstFeature("110001_0001__00001"), # bereits vorhanden
|
||||||
|
_DummyFlstFeature("110001_0002__00007"), # neu
|
||||||
|
])
|
||||||
|
mock_check.return_value = (bestehend, LoadStatus.APPEND)
|
||||||
|
mock_lade.return_value = neu_geladen
|
||||||
|
|
||||||
|
layer, status = flurstueck_alkis(
|
||||||
|
None, vorgabe_schluessel=["0001", "0002"], ohne_schluessel_abfrage=True
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_ask_text.assert_not_called()
|
||||||
|
self.assertEqual(status, LoadStatus.APPEND)
|
||||||
|
self.assertEqual(len(bestehend.added), 1)
|
||||||
|
self.assertEqual(bestehend.added[0][FELD_FLURSTUECKSKENNZEICHEN], "110001_0002__00007")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ if "qgis" not in sys.modules:
|
|||||||
|
|
||||||
from sn_verfahrensgebiet.functions.grenzpunkt_alkis import (
|
from sn_verfahrensgebiet.functions.grenzpunkt_alkis import (
|
||||||
grenzpunkt_alkis,
|
grenzpunkt_alkis,
|
||||||
|
grenzpunkte_gemarkungsweise,
|
||||||
_extrahiere_gml_ids,
|
_extrahiere_gml_ids,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -297,5 +298,134 @@ class TestGrenzpunktAlkis(unittest.TestCase):
|
|||||||
self.assertIs(gp, gp_layer)
|
self.assertIs(gp, gp_layer)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Tests: grenzpunkte_gemarkungsweise – Stilanbringung (#53)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
_G_PATCH_EXTENTS = "sn_verfahrensgebiet.functions.grenzpunkt_alkis._lade_gemarkung_extents"
|
||||||
|
_G_PATCH_HITS = "sn_verfahrensgebiet.functions.grenzpunkt_alkis._wfs_hits_count"
|
||||||
|
_G_PATCH_GET_GML = "sn_verfahrensgebiet.functions.grenzpunkt_alkis._wfs_get_gml"
|
||||||
|
_G_PATCH_PARSE_GML = "sn_verfahrensgebiet.functions.grenzpunkt_alkis._parse_alkis_gml_memory_layer"
|
||||||
|
_G_PATCH_ERKENNE_FELD = "sn_verfahrensgebiet.functions.grenzpunkt_alkis._erkenne_gehoert_zu_feld"
|
||||||
|
_G_PATCH_EXTRAHIERE_ID = "sn_verfahrensgebiet.functions.grenzpunkt_alkis._extrahiere_feature_gml_id"
|
||||||
|
_G_PATCH_LADE_GP_DICT = "sn_verfahrensgebiet.functions.grenzpunkt_alkis._lade_grenzpunkte_als_dict"
|
||||||
|
_G_PATCH_ERSTELLE_JOINED = "sn_verfahrensgebiet.functions.grenzpunkt_alkis._erstelle_joined_layer"
|
||||||
|
_G_PATCH_WFS_LAYER = "sn_verfahrensgebiet.functions.grenzpunkt_alkis.QgsVectorLayer"
|
||||||
|
_G_PATCH_PROJECT = "sn_verfahrensgebiet.functions.grenzpunkt_alkis.QgsProject"
|
||||||
|
_G_PATCH_PROGRESS = "sn_verfahrensgebiet.functions.grenzpunkt_alkis.create_progress_dialog"
|
||||||
|
_G_PATCH_APPLY_STIL = "sn_verfahrensgebiet.functions.grenzpunkt_alkis.apply_style"
|
||||||
|
# QgsField/QgsFeature werden innerhalb der Funktion per lokalem Import geholt
|
||||||
|
# (from sn_basis.functions import QgsField/QgsFeature) - Patch-Ziel ist daher
|
||||||
|
# die Quelle, nicht der Aufrufort.
|
||||||
|
_G_PATCH_QGSFIELD = "sn_basis.functions.QgsField"
|
||||||
|
_G_PATCH_QGSFEATURE = "sn_basis.functions.QgsFeature"
|
||||||
|
|
||||||
|
|
||||||
|
class _DummyProgress:
|
||||||
|
def set_value(self, wert): pass
|
||||||
|
def set_label(self, text): pass
|
||||||
|
def set_total(self, wert): pass
|
||||||
|
def is_canceled(self): return False
|
||||||
|
def close(self): pass
|
||||||
|
|
||||||
|
|
||||||
|
class _DummyBbox:
|
||||||
|
def xMinimum(self): return 414000.0
|
||||||
|
def yMinimum(self): return 5657000.0
|
||||||
|
def xMaximum(self): return 415000.0
|
||||||
|
def yMaximum(self): return 5658000.0
|
||||||
|
|
||||||
|
|
||||||
|
class _DummyGmlFeld:
|
||||||
|
def __init__(self, name):
|
||||||
|
self._name = name
|
||||||
|
|
||||||
|
def name(self):
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
|
||||||
|
class _DummyGmlFeature:
|
||||||
|
def __init__(self, gehoert_zu_wert):
|
||||||
|
self._wert = gehoert_zu_wert
|
||||||
|
|
||||||
|
def geometry(self):
|
||||||
|
return object()
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
if key == "gehoertZu":
|
||||||
|
return self._wert
|
||||||
|
raise KeyError(key)
|
||||||
|
|
||||||
|
|
||||||
|
class _DummyGmlLayer:
|
||||||
|
"""Minimaler Ersatz für das Ergebnis von _parse_alkis_gml_memory_layer()."""
|
||||||
|
|
||||||
|
def __init__(self, feature):
|
||||||
|
self._feature = feature
|
||||||
|
|
||||||
|
def fields(self):
|
||||||
|
return [_DummyGmlFeld("gehoertZu")]
|
||||||
|
|
||||||
|
def getFeatures(self):
|
||||||
|
return [self._feature]
|
||||||
|
|
||||||
|
|
||||||
|
class TestGrenzpunkteGemarkungsweiseStil(unittest.TestCase):
|
||||||
|
|
||||||
|
@patch(_G_PATCH_APPLY_STIL)
|
||||||
|
@patch(_G_PATCH_QGSFEATURE)
|
||||||
|
@patch(_G_PATCH_QGSFIELD)
|
||||||
|
@patch(_G_PATCH_PROGRESS)
|
||||||
|
@patch(_G_PATCH_PROJECT)
|
||||||
|
@patch(_G_PATCH_WFS_LAYER)
|
||||||
|
@patch(_G_PATCH_ERSTELLE_JOINED)
|
||||||
|
@patch(_G_PATCH_LADE_GP_DICT)
|
||||||
|
@patch(_G_PATCH_EXTRAHIERE_ID)
|
||||||
|
@patch(_G_PATCH_ERKENNE_FELD)
|
||||||
|
@patch(_G_PATCH_PARSE_GML)
|
||||||
|
@patch(_G_PATCH_GET_GML)
|
||||||
|
@patch(_G_PATCH_HITS)
|
||||||
|
@patch(_G_PATCH_EXTENTS)
|
||||||
|
def test_stil_wird_nach_dem_laden_auf_den_ergebnis_layer_angewendet(
|
||||||
|
self,
|
||||||
|
mock_extents,
|
||||||
|
mock_hits,
|
||||||
|
mock_get_gml,
|
||||||
|
mock_parse_gml,
|
||||||
|
mock_erkenne_feld,
|
||||||
|
mock_extrahiere_id,
|
||||||
|
mock_lade_gp_dict,
|
||||||
|
mock_erstelle_joined,
|
||||||
|
mock_wfs_layer_cls,
|
||||||
|
mock_project_cls,
|
||||||
|
mock_progress,
|
||||||
|
mock_qgsfield,
|
||||||
|
mock_qgsfeature,
|
||||||
|
mock_apply_style,
|
||||||
|
):
|
||||||
|
"""Prüft, dass grenzpunkte_gemarkungsweise() nach dem Laden apply_style() mit dem neuen ALKIS-Grenzpunkt-Stil auf den fertigen Join-Layer anwendet (#53)."""
|
||||||
|
mock_extents.return_value = {"1234": _DummyBbox()}
|
||||||
|
mock_hits.return_value = 1
|
||||||
|
mock_get_gml.return_value = b"<fake/>"
|
||||||
|
mock_parse_gml.return_value = _DummyGmlLayer(_DummyGmlFeature("urn:adv:oid:GP1"))
|
||||||
|
mock_erkenne_feld.return_value = "gehoertZu"
|
||||||
|
mock_extrahiere_id.return_value = "PTA1"
|
||||||
|
mock_lade_gp_dict.return_value = ({"GP1": object()}, ["gp_feld"])
|
||||||
|
|
||||||
|
joined_layer = MagicMock()
|
||||||
|
mock_erstelle_joined.return_value = joined_layer
|
||||||
|
mock_wfs_layer_cls.return_value = MagicMock()
|
||||||
|
|
||||||
|
project = MagicMock()
|
||||||
|
mock_project_cls.instance.return_value = project
|
||||||
|
mock_progress.return_value = _DummyProgress()
|
||||||
|
|
||||||
|
ergebnis = grenzpunkte_gemarkungsweise(None, ["1234"])
|
||||||
|
|
||||||
|
self.assertIs(ergebnis, joined_layer)
|
||||||
|
project.addMapLayer.assert_called_once_with(joined_layer)
|
||||||
|
mock_apply_style.assert_called_once_with(joined_layer, "alkis_grenzpunkte.qml")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
@@ -81,6 +81,30 @@ class _DummyCombo:
|
|||||||
self.layer = layer
|
self.layer = layer
|
||||||
|
|
||||||
|
|
||||||
|
class _DummyGemFeature:
|
||||||
|
def __init__(self, schluessel, name):
|
||||||
|
self._schluessel = schluessel
|
||||||
|
self._name = name
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
if key == "schluessel":
|
||||||
|
return self._schluessel
|
||||||
|
if key == "ave_name":
|
||||||
|
return self._name
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class _DummyGemarkungenLayer:
|
||||||
|
def __init__(self, selected):
|
||||||
|
self._selected = list(selected)
|
||||||
|
|
||||||
|
def selectedFeatureCount(self):
|
||||||
|
return len(self._selected)
|
||||||
|
|
||||||
|
def selectedFeatures(self):
|
||||||
|
return list(self._selected)
|
||||||
|
|
||||||
|
|
||||||
class TestWorkingTab(unittest.TestCase):
|
class TestWorkingTab(unittest.TestCase):
|
||||||
|
|
||||||
def _make_tab(self):
|
def _make_tab(self):
|
||||||
@@ -96,6 +120,7 @@ class TestWorkingTab(unittest.TestCase):
|
|||||||
tab.haken_flurst = types.SimpleNamespace(setText=lambda _t: None, setStyleSheet=lambda _s: None)
|
tab.haken_flurst = types.SimpleNamespace(setText=lambda _t: None, setStyleSheet=lambda _s: None)
|
||||||
tab.haken_gem = types.SimpleNamespace(setText=lambda _t: None, setStyleSheet=lambda _s: None)
|
tab.haken_gem = types.SimpleNamespace(setText=lambda _t: None, setStyleSheet=lambda _s: None)
|
||||||
tab.haken_grenz = types.SimpleNamespace(setText=lambda _t: None, setStyleSheet=lambda _s: None)
|
tab.haken_grenz = types.SimpleNamespace(setText=lambda _t: None, setStyleSheet=lambda _s: None)
|
||||||
|
tab.btn_flurst_aus_gemarkungen = _DummyButton()
|
||||||
tab.setze_haken = lambda *_args, **_kwargs: None
|
tab.setze_haken = lambda *_args, **_kwargs: None
|
||||||
# Pruefmanager-Mock: verarbeite() wird im Test ggf. überschrieben
|
# Pruefmanager-Mock: verarbeite() wird im Test ggf. überschrieben
|
||||||
tab.pruefmanager = types.SimpleNamespace(
|
tab.pruefmanager = types.SimpleNamespace(
|
||||||
@@ -175,6 +200,83 @@ class TestWorkingTab(unittest.TestCase):
|
|||||||
|
|
||||||
mock_set_layer_id.assert_called_once_with("")
|
mock_set_layer_id.assert_called_once_with("")
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# handle_flurst_alkis / handle_flurst_aus_gemarkungen (#47: eine gemeinsame
|
||||||
|
# Ladelogik in flurstueck_alkis(), hier wird nur noch die Anbindung geprüft)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.success")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.apply_style")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.flurstueck_alkis")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||||||
|
def test_handle_flurst_alkis_first_load_uebernimmt_layer(
|
||||||
|
self, mock_iface, mock_project_instance, mock_flurstueck_alkis, mock_apply_style, mock_success
|
||||||
|
):
|
||||||
|
"""Erstmaliges Laden über 'Flurstücke laden' fügt den Layer dem Projekt hinzu."""
|
||||||
|
tab = self._make_tab()
|
||||||
|
mock_iface.mapCanvas.return_value = _DummyCanvas()
|
||||||
|
project = _DummyProject()
|
||||||
|
mock_project_instance.return_value = project
|
||||||
|
layer = _DummyLayer(valid=True, layer_id="flst_first")
|
||||||
|
mock_flurstueck_alkis.return_value = (layer, LoadStatus.FIRST)
|
||||||
|
|
||||||
|
tab.handle_flurst_alkis()
|
||||||
|
|
||||||
|
mock_flurstueck_alkis.assert_called_once_with(tab)
|
||||||
|
self.assertIn(layer, project.added)
|
||||||
|
mock_success.assert_called_once()
|
||||||
|
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.success")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.flurstueck_alkis")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||||||
|
def test_handle_flurst_aus_gemarkungen_ruft_flurstueck_alkis_ohne_schluessel_abfrage(
|
||||||
|
self, mock_iface, mock_project_instance, mock_flurstueck_alkis, mock_success
|
||||||
|
):
|
||||||
|
"""Der Gemarkungen-Auswahl-Button ruft dieselbe Ladefunktion mit ohne_schluessel_abfrage=True auf (#47)."""
|
||||||
|
tab = self._make_tab()
|
||||||
|
mock_iface.mapCanvas.return_value = _DummyCanvas()
|
||||||
|
gem_feat = _DummyGemFeature("110001", "Musterstadt")
|
||||||
|
gem_layer = _DummyGemarkungenLayer([gem_feat])
|
||||||
|
project = types.SimpleNamespace(
|
||||||
|
mapLayersByName=lambda name: [gem_layer] if name == "Gemarkungen" else []
|
||||||
|
)
|
||||||
|
mock_project_instance.return_value = project
|
||||||
|
layer = _DummyLayer(valid=True, layer_id="flst_append")
|
||||||
|
mock_flurstueck_alkis.return_value = (layer, LoadStatus.APPEND)
|
||||||
|
|
||||||
|
tab.handle_flurst_aus_gemarkungen()
|
||||||
|
|
||||||
|
mock_flurstueck_alkis.assert_called_once()
|
||||||
|
_args, kwargs = mock_flurstueck_alkis.call_args
|
||||||
|
self.assertEqual(kwargs.get("vorgabe_schluessel"), ["0001"])
|
||||||
|
self.assertEqual(kwargs.get("vorgabe_namen"), ["Musterstadt"])
|
||||||
|
self.assertTrue(kwargs.get("ohne_schluessel_abfrage"))
|
||||||
|
mock_success.assert_called_once()
|
||||||
|
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.error")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.success")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.flurstueck_alkis")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||||||
|
def test_handle_flurst_aus_gemarkungen_abbruch_zeigt_keine_zusaetzliche_meldung(
|
||||||
|
self, mock_project_instance, mock_flurstueck_alkis, mock_success, mock_error
|
||||||
|
):
|
||||||
|
"""Bricht flurstueck_alkis() ab (None, NONE), zeigt der Button keine eigene Meldung – flurstueck_alkis() hat das schon getan (#47)."""
|
||||||
|
tab = self._make_tab()
|
||||||
|
gem_feat = _DummyGemFeature("110001", "Musterstadt")
|
||||||
|
gem_layer = _DummyGemarkungenLayer([gem_feat])
|
||||||
|
project = types.SimpleNamespace(
|
||||||
|
mapLayersByName=lambda name: [gem_layer] if name == "Gemarkungen" else []
|
||||||
|
)
|
||||||
|
mock_project_instance.return_value = project
|
||||||
|
mock_flurstueck_alkis.return_value = (None, LoadStatus.NONE)
|
||||||
|
|
||||||
|
tab.handle_flurst_aus_gemarkungen()
|
||||||
|
|
||||||
|
mock_success.assert_not_called()
|
||||||
|
mock_error.assert_not_called()
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# handle_grenz_alkis
|
# handle_grenz_alkis
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
@@ -822,6 +924,68 @@ class TestHandleVerfShape(unittest.TestCase):
|
|||||||
self.assertIn(False, busy_states, "Button muss am Ende wieder freigegeben werden")
|
self.assertIn(False, busy_states, "Button muss am Ende wieder freigegeben werden")
|
||||||
|
|
||||||
|
|
||||||
|
class TestZoomImProjektKbs(unittest.TestCase):
|
||||||
|
"""Zoom auf das neue Verfahrensgebiet rechnet in das KBS der Kartenansicht um (Basis #99)."""
|
||||||
|
|
||||||
|
def _tab(self):
|
||||||
|
tab = TestWorkingTab._make_tab(TestWorkingTab())
|
||||||
|
tab.setze_haken = lambda *_: None
|
||||||
|
tab._on_verf_layer_changed = lambda *_: None
|
||||||
|
return tab
|
||||||
|
|
||||||
|
def _projekt(self, mock_project_instance):
|
||||||
|
proj = _DummyProject()
|
||||||
|
proj.mapLayersByName = lambda _n: []
|
||||||
|
proj.mapLayer = lambda _lid: None
|
||||||
|
mock_project_instance.return_value = proj
|
||||||
|
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.zoom_auf_layer")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.success")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.apply_style")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_alkis_komplett")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
|
||||||
|
def test_alkis_zoom_ueber_zoom_auf_layer(self, _set_id, mock_iface, mock_alkis, mock_projekt,
|
||||||
|
_stil, _erfolg, mock_zoom):
|
||||||
|
"""Prüft, dass nach dem Laden aus ALKIS über zoom_auf_layer auf das Verfahrensgebiet gezoomt wird und nicht mit der unumgerechneten Layer-Ausdehnung."""
|
||||||
|
tab = self._tab()
|
||||||
|
enriched = _DummyLayer(valid=True, layer_id="vg")
|
||||||
|
mock_alkis.return_value = (enriched, _DummyLayer(layer_id="flst"), None, LoadStatus.FIRST)
|
||||||
|
self._projekt(mock_projekt)
|
||||||
|
canvas = _DummyCanvas()
|
||||||
|
mock_iface.mapCanvas.return_value = canvas
|
||||||
|
|
||||||
|
tab.handle_verf_alkis()
|
||||||
|
|
||||||
|
mock_zoom.assert_called_once_with(enriched, canvas)
|
||||||
|
self.assertIsNone(canvas.extent)
|
||||||
|
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.get_variable", return_value="VF-123")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.zoom_auf_layer")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.success")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.apply_style")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.QgsProject.instance")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.verfahrensgebiet_shape_komplett")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.iface")
|
||||||
|
@patch("sn_verfahrensgebiet.ui.tabs.working_tab.set_verfahrensgebiet_layer_id")
|
||||||
|
def test_shape_zoom_ueber_zoom_auf_layer(self, _set_id, mock_iface, mock_shape, mock_projekt,
|
||||||
|
_stil, _erfolg, mock_zoom, _var):
|
||||||
|
"""Prüft, dass nach dem Laden aus einem Shape über zoom_auf_layer auf das Verfahrensgebiet gezoomt wird und nicht mit der unumgerechneten Layer-Ausdehnung."""
|
||||||
|
tab = self._tab()
|
||||||
|
tab.btn_verf_shape = _DummyButton()
|
||||||
|
enriched = _DummyLayer(valid=True, layer_id="shape_vg")
|
||||||
|
mock_shape.return_value = (enriched, _DummyLayer(layer_id="flst"), None, LoadStatus.FIRST)
|
||||||
|
self._projekt(mock_projekt)
|
||||||
|
canvas = _DummyCanvas()
|
||||||
|
mock_iface.mapCanvas.return_value = canvas
|
||||||
|
|
||||||
|
tab.handle_verf_shape()
|
||||||
|
|
||||||
|
mock_zoom.assert_called_once_with(enriched, canvas)
|
||||||
|
self.assertIsNone(canvas.extent)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ class DockWidget(BaseDockWidget):
|
|||||||
self._init_tabs_with_services()
|
self._init_tabs_with_services()
|
||||||
|
|
||||||
def _init_tabs_with_services(self):
|
def _init_tabs_with_services(self):
|
||||||
"""Tabs neu aufbauen und Services (z.B. fuer PrintTab) injizieren."""
|
"""Tabs neu aufbauen und Services (z.B. für PrintTab) injizieren."""
|
||||||
try:
|
try:
|
||||||
self.setWidget(None)
|
self.setWidget(None)
|
||||||
|
|
||||||
|
|||||||
+31
-83
@@ -5,7 +5,7 @@ Verwaltet die Verfahrensgebiet-Abgrenzung und ALKIS-Integration.
|
|||||||
from sn_basis.functions.qt_wrapper import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QMessageBox
|
from sn_basis.functions.qt_wrapper import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QMessageBox
|
||||||
from sn_basis.functions.qt_wrapper import Qt
|
from sn_basis.functions.qt_wrapper import Qt
|
||||||
from sn_basis.functions import Qgis, QgsProject #QgsMessageLog
|
from sn_basis.functions import Qgis, QgsProject #QgsMessageLog
|
||||||
from sn_basis.functions.qgisui_wrapper import QgsMapLayerComboBox
|
from sn_basis.functions.qgisui_wrapper import QgsMapLayerComboBox, zoom_auf_layer
|
||||||
from sn_basis.functions.qgiscore_wrapper import QgsMapLayerProxyModel
|
from sn_basis.functions.qgiscore_wrapper import QgsMapLayerProxyModel
|
||||||
from sn_basis.functions.verfahrensgebiet_manager import get_verfahrensgebiet_layer_id, set_verfahrensgebiet_layer_id
|
from sn_basis.functions.verfahrensgebiet_manager import get_verfahrensgebiet_layer_id, set_verfahrensgebiet_layer_id
|
||||||
from sn_basis.functions.dialog_wrapper import show_info_dialog, create_progress_dialog, ask_yes_no
|
from sn_basis.functions.dialog_wrapper import show_info_dialog, create_progress_dialog, ask_yes_no
|
||||||
@@ -15,12 +15,7 @@ from sn_basis.modules.pruef_ergebnis import pruef_ergebnis
|
|||||||
from qgis.utils import iface
|
from qgis.utils import iface
|
||||||
|
|
||||||
from sn_verfahrensgebiet.functions.verfahrensgebiet_alkis import LoadStatus
|
from sn_verfahrensgebiet.functions.verfahrensgebiet_alkis import LoadStatus
|
||||||
from sn_verfahrensgebiet.functions.flurstueck_alkis import (
|
from sn_verfahrensgebiet.functions.flurstueck_alkis import flurstueck_alkis
|
||||||
flurstueck_alkis,
|
|
||||||
lade_flurstuecke_per_gemarkung,
|
|
||||||
ALKIS_SF_URL,
|
|
||||||
FLST_LAYER_NAME,
|
|
||||||
)
|
|
||||||
from sn_verfahrensgebiet.functions.verfahrensgebiet_alkis_komplett import (
|
from sn_verfahrensgebiet.functions.verfahrensgebiet_alkis_komplett import (
|
||||||
verfahrensgebiet_alkis_komplett,
|
verfahrensgebiet_alkis_komplett,
|
||||||
BROR_LAYER_NAME,
|
BROR_LAYER_NAME,
|
||||||
@@ -230,8 +225,8 @@ class WorkingTab(QWidget):
|
|||||||
if not project.mapLayer(enriched_layer.id()):
|
if not project.mapLayer(enriched_layer.id()):
|
||||||
project.addMapLayer(enriched_layer)
|
project.addMapLayer(enriched_layer)
|
||||||
apply_style(enriched_layer, "verfahrensgebiet.qml")
|
apply_style(enriched_layer, "verfahrensgebiet.qml")
|
||||||
iface.mapCanvas().setExtent(enriched_layer.extent())
|
# Ausdehnung ins KBS der Kartenansicht umrechnen (Basis #99)
|
||||||
iface.mapCanvas().refresh()
|
zoom_auf_layer(enriched_layer, iface.mapCanvas())
|
||||||
self.setze_haken(self.haken_verf, True)
|
self.setze_haken(self.haken_verf, True)
|
||||||
|
|
||||||
self.verf_layer_combo.setLayer(enriched_layer)
|
self.verf_layer_combo.setLayer(enriched_layer)
|
||||||
@@ -287,8 +282,8 @@ class WorkingTab(QWidget):
|
|||||||
if not project.mapLayer(enriched_layer.id()):
|
if not project.mapLayer(enriched_layer.id()):
|
||||||
project.addMapLayer(enriched_layer)
|
project.addMapLayer(enriched_layer)
|
||||||
apply_style(enriched_layer, "verfahrensgebiet.qml")
|
apply_style(enriched_layer, "verfahrensgebiet.qml")
|
||||||
iface.mapCanvas().setExtent(enriched_layer.extent())
|
# Ausdehnung ins KBS der Kartenansicht umrechnen (Basis #99)
|
||||||
iface.mapCanvas().refresh()
|
zoom_auf_layer(enriched_layer, iface.mapCanvas())
|
||||||
self.setze_haken(self.haken_verf, True)
|
self.setze_haken(self.haken_verf, True)
|
||||||
|
|
||||||
self.verf_layer_combo.setLayer(enriched_layer)
|
self.verf_layer_combo.setLayer(enriched_layer)
|
||||||
@@ -392,6 +387,25 @@ class WorkingTab(QWidget):
|
|||||||
# Flurstücke-Handler
|
# Flurstücke-Handler
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def _uebernimm_flurstuecke_ergebnis(self, layer, status) -> None:
|
||||||
|
"""Übernimmt das Ergebnis von flurstueck_alkis() ins Projekt (FIRST/RELOAD/APPEND/KEEP)."""
|
||||||
|
if status in (LoadStatus.FIRST, LoadStatus.RELOAD):
|
||||||
|
QgsProject.instance().addMapLayer(layer)
|
||||||
|
apply_style(layer, "GIS_Flst_Beschriftung_ALKIS_NAS.qml")
|
||||||
|
iface.mapCanvas().refresh()
|
||||||
|
self.setze_haken(self.haken_flurst, True)
|
||||||
|
msg = "erstmalig geladen" if status == LoadStatus.FIRST else "neu geladen"
|
||||||
|
success("Flurstücke", f"Layer wurde {msg}.", duration=5)
|
||||||
|
|
||||||
|
elif status == LoadStatus.KEEP:
|
||||||
|
self.setze_haken(self.haken_flurst, True)
|
||||||
|
info("Flurstücke", "Vorhandener Layer wurde behalten.", duration=4)
|
||||||
|
|
||||||
|
elif status == LoadStatus.APPEND:
|
||||||
|
self.setze_haken(self.haken_flurst, True)
|
||||||
|
iface.mapCanvas().refresh()
|
||||||
|
success("Flurstücke", "Features wurden an den vorhandenen Layer angehängt.", duration=5)
|
||||||
|
|
||||||
def handle_flurst_alkis(self) -> None:
|
def handle_flurst_alkis(self) -> None:
|
||||||
"""Lädt Flurstücke aus ALKIS-WFS anhand von Gemarkungsschlüsseln."""
|
"""Lädt Flurstücke aus ALKIS-WFS anhand von Gemarkungsschlüsseln."""
|
||||||
self._set_busy(self.btn_flurst_alkis, True, "Aus ALKIS laden")
|
self._set_busy(self.btn_flurst_alkis, True, "Aus ALKIS laden")
|
||||||
@@ -399,25 +413,7 @@ class WorkingTab(QWidget):
|
|||||||
layer, status = flurstueck_alkis(self)
|
layer, status = flurstueck_alkis(self)
|
||||||
if not layer or not layer.isValid():
|
if not layer or not layer.isValid():
|
||||||
return
|
return
|
||||||
|
self._uebernimm_flurstuecke_ergebnis(layer, status)
|
||||||
if status in (LoadStatus.FIRST, LoadStatus.RELOAD):
|
|
||||||
QgsProject.instance().addMapLayer(layer)
|
|
||||||
# iface.mapCanvas().setExtent(layer.extent()) # Kartenausschnitt bleibt unverändert
|
|
||||||
apply_style(layer, "GIS_Flst_Beschriftung_ALKIS_NAS.qml")
|
|
||||||
iface.mapCanvas().refresh()
|
|
||||||
self.setze_haken(self.haken_flurst, True)
|
|
||||||
msg = "erstmalig geladen" if status == LoadStatus.FIRST else "neu geladen"
|
|
||||||
success("Flurstücke", f"Layer wurde {msg}.", duration=5)
|
|
||||||
|
|
||||||
elif status == LoadStatus.KEEP:
|
|
||||||
self.setze_haken(self.haken_flurst, True)
|
|
||||||
info("Flurstücke", "Vorhandener Layer wurde behalten.", duration=4)
|
|
||||||
|
|
||||||
elif status == LoadStatus.APPEND:
|
|
||||||
self.setze_haken(self.haken_flurst, True)
|
|
||||||
iface.mapCanvas().refresh()
|
|
||||||
success("Flurstücke", "Features wurden an den vorhandenen Layer angehängt.", duration=5)
|
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
self._set_busy(self.btn_flurst_alkis, False, "Aus ALKIS laden")
|
self._set_busy(self.btn_flurst_alkis, False, "Aus ALKIS laden")
|
||||||
|
|
||||||
@@ -491,68 +487,20 @@ class WorkingTab(QWidget):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Prüfen ob bereits ein Flurstücke-Layer vorhanden → 3-Knopf-Dialog
|
# Flurstücke laden – Schlüssel bereits bekannt, aber bei bestehendem Layer
|
||||||
existing_flst = project.mapLayersByName(FLST_LAYER_NAME)
|
# trotzdem interaktiv nachfragen (Überschreiben/Anhängen/Abbrechen, inkl. Dedup)
|
||||||
if existing_flst:
|
|
||||||
msg_box = QMessageBox(self)
|
|
||||||
msg_box.setWindowTitle("Layer bereits vorhanden")
|
|
||||||
msg_box.setText(
|
|
||||||
f"Der Layer '{FLST_LAYER_NAME}' existiert bereits.\nWas soll geschehen?"
|
|
||||||
)
|
|
||||||
btn_ueberschreiben = msg_box.addButton("Überschreiben", QMessageBox.ButtonRole.DestructiveRole)
|
|
||||||
btn_anhaengen = msg_box.addButton("Anhängen", QMessageBox.ButtonRole.AcceptRole)
|
|
||||||
btn_abbrechen = msg_box.addButton("Abbrechen", QMessageBox.ButtonRole.RejectRole)
|
|
||||||
msg_box.setDefaultButton(btn_abbrechen)
|
|
||||||
msg_box.exec()
|
|
||||||
clicked = msg_box.clickedButton()
|
|
||||||
if clicked is btn_abbrechen:
|
|
||||||
return
|
|
||||||
if clicked is btn_anhaengen:
|
|
||||||
temp_layer = lade_flurstuecke_per_gemarkung(vorgabe_schluessel)
|
|
||||||
if not temp_layer or not temp_layer.isValid() or temp_layer.featureCount() == 0:
|
|
||||||
error(
|
|
||||||
"Flurstücke",
|
|
||||||
f"Flurstücke konnten nicht geladen werden – WFS-Dienst ({ALKIS_SF_URL}) "
|
|
||||||
f"nicht erreichbar oder keine Features für die gewählten Gemarkungen.",
|
|
||||||
duration=0,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
existing_flst[0].dataProvider().addFeatures(list(temp_layer.getFeatures()))
|
|
||||||
existing_flst[0].updateExtents()
|
|
||||||
iface.mapCanvas().refresh()
|
|
||||||
self.setze_haken(self.haken_flurst, True)
|
|
||||||
success("Flurstücke", "Features wurden an den vorhandenen Layer angehängt.", duration=5)
|
|
||||||
return
|
|
||||||
# else: Überschreiben → fall-through zum flurstueck_alkis(ohne_dialog=True)-Aufruf
|
|
||||||
|
|
||||||
# Flurstücke direkt laden (kein Dialog)
|
|
||||||
layer, status = flurstueck_alkis(
|
layer, status = flurstueck_alkis(
|
||||||
self,
|
self,
|
||||||
vorgabe_schluessel=vorgabe_schluessel,
|
vorgabe_schluessel=vorgabe_schluessel,
|
||||||
vorgabe_namen=vorgabe_namen,
|
vorgabe_namen=vorgabe_namen,
|
||||||
ohne_dialog=True,
|
ohne_schluessel_abfrage=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not layer or not layer.isValid():
|
if not layer or not layer.isValid():
|
||||||
error(
|
# flurstueck_alkis() hat bei Abbruch/Fehler bereits selbst eine Meldung gezeigt.
|
||||||
"Flurstücke",
|
|
||||||
f"Flurstücke konnten nicht geladen werden – WFS-Dienst ({ALKIS_SF_URL}) "
|
|
||||||
f"nicht erreichbar oder keine Features für die gewählten Gemarkungen.",
|
|
||||||
duration=0,
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if status in (LoadStatus.FIRST, LoadStatus.RELOAD):
|
self._uebernimm_flurstuecke_ergebnis(layer, status)
|
||||||
project.addMapLayer(layer)
|
|
||||||
apply_style(layer, "GIS_Flst_Beschriftung_ALKIS_NAS.qml")
|
|
||||||
iface.mapCanvas().refresh()
|
|
||||||
self.setze_haken(self.haken_flurst, True)
|
|
||||||
msg = "erstmalig geladen" if status == LoadStatus.FIRST else "neu geladen"
|
|
||||||
success("Flurstücke", f"Layer wurde {msg}.", duration=5)
|
|
||||||
|
|
||||||
elif status == LoadStatus.KEEP:
|
|
||||||
self.setze_haken(self.haken_flurst, True)
|
|
||||||
info("Flurstücke", "Vorhandener Layer wurde behalten.", duration=4)
|
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
self._set_busy(self.btn_flurst_aus_gemarkungen, False, "aus gewählten Gemarkungen laden")
|
self._set_busy(self.btn_flurst_aus_gemarkungen, False, "aus gewählten Gemarkungen laden")
|
||||||
|
|||||||
Reference in New Issue
Block a user