2025-12-18 22:00:31 +01:00
|
|
|
|
"""
|
|
|
|
|
|
sn_basis/modules/layerpruefer.py – Prüfung von QGIS-Layern.
|
2025-12-19 14:29:52 +01:00
|
|
|
|
Verwendet ausschließlich Wrapper und gibt pruef_ergebnis zurück.
|
2025-12-18 22:00:31 +01:00
|
|
|
|
"""
|
|
|
|
|
|
|
2025-12-19 14:29:52 +01:00
|
|
|
|
from sn_basis.functions import (
|
2025-12-18 22:00:31 +01:00
|
|
|
|
layer_exists,
|
|
|
|
|
|
get_layer_geometry_type,
|
|
|
|
|
|
get_layer_feature_count,
|
|
|
|
|
|
is_layer_visible,
|
|
|
|
|
|
get_layer_type,
|
|
|
|
|
|
get_layer_crs,
|
|
|
|
|
|
get_layer_fields,
|
|
|
|
|
|
get_layer_source,
|
|
|
|
|
|
is_layer_editable,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2025-12-19 14:29:52 +01:00
|
|
|
|
from sn_basis.modules.pruef_ergebnis import pruef_ergebnis, PruefAktion
|
2025-12-18 22:00:31 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Layerpruefer:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Prüft Layer auf Existenz, Sichtbarkeit, Geometrietyp, Objektanzahl,
|
|
|
|
|
|
Layertyp, CRS, Felder, Datenquelle und Editierbarkeit.
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
|
|
self,
|
|
|
|
|
|
layer,
|
|
|
|
|
|
erwarteter_geotyp: str | None = None,
|
|
|
|
|
|
muss_sichtbar_sein: bool = False,
|
|
|
|
|
|
erwarteter_layertyp: str | None = None,
|
|
|
|
|
|
erwartetes_crs: str | None = None,
|
|
|
|
|
|
erforderliche_felder: list[str] | None = None,
|
|
|
|
|
|
erlaubte_datenquellen: list[str] | None = None,
|
|
|
|
|
|
muss_editierbar_sein: bool = False,
|
|
|
|
|
|
):
|
|
|
|
|
|
self.layer = layer
|
|
|
|
|
|
self.erwarteter_geotyp = erwarteter_geotyp
|
|
|
|
|
|
self.muss_sichtbar_sein = muss_sichtbar_sein
|
|
|
|
|
|
self.erwarteter_layertyp = erwarteter_layertyp
|
|
|
|
|
|
self.erwartetes_crs = erwartetes_crs
|
|
|
|
|
|
self.erforderliche_felder = erforderliche_felder or []
|
|
|
|
|
|
self.erlaubte_datenquellen = erlaubte_datenquellen or []
|
|
|
|
|
|
self.muss_editierbar_sein = muss_editierbar_sein
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
|
# Hauptfunktion
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
def pruefe(self) -> pruef_ergebnis:
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# 1. Existenz
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
if not layer_exists(self.layer):
|
|
|
|
|
|
return pruef_ergebnis(
|
|
|
|
|
|
ok=False,
|
|
|
|
|
|
meldung="Der Layer existiert nicht oder wurde nicht geladen.",
|
2025-12-19 14:29:52 +01:00
|
|
|
|
aktion="layer_nicht_gefunden",
|
|
|
|
|
|
kontext=None,
|
2025-12-18 22:00:31 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# 2. Sichtbarkeit
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
sichtbar = is_layer_visible(self.layer)
|
|
|
|
|
|
if self.muss_sichtbar_sein and not sichtbar:
|
|
|
|
|
|
return pruef_ergebnis(
|
|
|
|
|
|
ok=False,
|
|
|
|
|
|
meldung="Der Layer ist unsichtbar. Soll er eingeblendet werden?",
|
2025-12-19 14:29:52 +01:00
|
|
|
|
aktion="layer_unsichtbar",
|
|
|
|
|
|
kontext=self.layer, # Layerobjekt als Kontext
|
2025-12-18 22:00:31 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# 3. Layertyp
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
layertyp = get_layer_type(self.layer)
|
|
|
|
|
|
if self.erwarteter_layertyp and layertyp != self.erwarteter_layertyp:
|
|
|
|
|
|
return pruef_ergebnis(
|
|
|
|
|
|
ok=False,
|
2025-12-19 14:29:52 +01:00
|
|
|
|
meldung=(
|
|
|
|
|
|
f"Der Layer hat den Typ '{layertyp}', "
|
|
|
|
|
|
f"erwartet wurde '{self.erwarteter_layertyp}'."
|
|
|
|
|
|
),
|
2025-12-18 22:00:31 +01:00
|
|
|
|
aktion="falscher_layertyp",
|
2025-12-19 14:29:52 +01:00
|
|
|
|
kontext=None,
|
2025-12-18 22:00:31 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# 4. Geometrietyp
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
geotyp = get_layer_geometry_type(self.layer)
|
|
|
|
|
|
if self.erwarteter_geotyp and geotyp != self.erwarteter_geotyp:
|
|
|
|
|
|
return pruef_ergebnis(
|
|
|
|
|
|
ok=False,
|
2025-12-19 14:29:52 +01:00
|
|
|
|
meldung=(
|
|
|
|
|
|
f"Der Layer hat den Geometrietyp '{geotyp}', "
|
|
|
|
|
|
f"erwartet wurde '{self.erwarteter_geotyp}'."
|
|
|
|
|
|
),
|
2025-12-18 22:00:31 +01:00
|
|
|
|
aktion="falscher_geotyp",
|
2025-12-19 14:29:52 +01:00
|
|
|
|
kontext=None,
|
2025-12-18 22:00:31 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# 5. Featureanzahl
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
anzahl = get_layer_feature_count(self.layer)
|
|
|
|
|
|
if anzahl == 0:
|
|
|
|
|
|
return pruef_ergebnis(
|
|
|
|
|
|
ok=False,
|
|
|
|
|
|
meldung="Der Layer enthält keine Objekte.",
|
|
|
|
|
|
aktion="layer_leer",
|
2025-12-19 14:29:52 +01:00
|
|
|
|
kontext=None,
|
2025-12-18 22:00:31 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# 6. CRS
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
crs = get_layer_crs(self.layer)
|
|
|
|
|
|
if self.erwartetes_crs and crs != self.erwartetes_crs:
|
|
|
|
|
|
return pruef_ergebnis(
|
|
|
|
|
|
ok=False,
|
2025-12-19 14:29:52 +01:00
|
|
|
|
meldung=(
|
|
|
|
|
|
f"Der Layer hat das CRS '{crs}', "
|
|
|
|
|
|
f"erwartet wurde '{self.erwartetes_crs}'."
|
|
|
|
|
|
),
|
2025-12-18 22:00:31 +01:00
|
|
|
|
aktion="falsches_crs",
|
2025-12-19 14:29:52 +01:00
|
|
|
|
kontext=None,
|
2025-12-18 22:00:31 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# 7. Felder
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
felder = get_layer_fields(self.layer)
|
|
|
|
|
|
fehlende = [f for f in self.erforderliche_felder if f not in felder]
|
|
|
|
|
|
|
|
|
|
|
|
if fehlende:
|
|
|
|
|
|
return pruef_ergebnis(
|
|
|
|
|
|
ok=False,
|
2025-12-19 14:29:52 +01:00
|
|
|
|
meldung=(
|
|
|
|
|
|
"Der Layer enthält nicht alle erforderlichen Felder: "
|
|
|
|
|
|
+ ", ".join(fehlende)
|
|
|
|
|
|
),
|
2025-12-18 22:00:31 +01:00
|
|
|
|
aktion="felder_fehlen",
|
2025-12-19 14:29:52 +01:00
|
|
|
|
kontext=None,
|
2025-12-18 22:00:31 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# 8. Datenquelle
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
quelle = get_layer_source(self.layer)
|
|
|
|
|
|
if self.erlaubte_datenquellen and quelle not in self.erlaubte_datenquellen:
|
|
|
|
|
|
return pruef_ergebnis(
|
|
|
|
|
|
ok=False,
|
|
|
|
|
|
meldung=f"Die Datenquelle '{quelle}' ist nicht erlaubt.",
|
|
|
|
|
|
aktion="datenquelle_unerwartet",
|
2025-12-19 14:29:52 +01:00
|
|
|
|
kontext=None,
|
2025-12-18 22:00:31 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# 9. Editierbarkeit
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
editable = is_layer_editable(self.layer)
|
|
|
|
|
|
if self.muss_editierbar_sein and not editable:
|
|
|
|
|
|
return pruef_ergebnis(
|
|
|
|
|
|
ok=False,
|
|
|
|
|
|
meldung="Der Layer ist nicht editierbar.",
|
|
|
|
|
|
aktion="layer_nicht_editierbar",
|
2025-12-19 14:29:52 +01:00
|
|
|
|
kontext=None,
|
2025-12-18 22:00:31 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# 10. Alles OK
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
return pruef_ergebnis(
|
|
|
|
|
|
ok=True,
|
|
|
|
|
|
meldung="Layerprüfung erfolgreich.",
|
|
|
|
|
|
aktion="ok",
|
2025-12-19 14:29:52 +01:00
|
|
|
|
kontext=None,
|
2025-12-18 22:00:31 +01:00
|
|
|
|
)
|