Button Fachdaten laden hinzugefügt und angebunden (pipeline datagrabber-prüfer-datenlader-datenschreiber)

This commit is contained in:
2026-02-14 22:15:58 +01:00
parent 93b17e154c
commit b5f663d9de
3 changed files with 282 additions and 116 deletions

View File

@@ -16,7 +16,7 @@ from sn_basis.functions.qt_wrapper import (
ArrowRight,
SizePolicyPreferred,
SizePolicyMaximum,
ComboBox,
QComboBox,
)
from sn_basis.functions.qgisui_wrapper import QgsFileWidget, QgsMapLayerComboBox
from sn_basis.functions.qgiscore_wrapper import QgsProject, QgsMapLayerProxyModel
@@ -30,13 +30,15 @@ from sn_basis.modules.Pruefmanager import Pruefmanager
from sn_basis.modules.DataGrabber import DataGrabber
from sn_basis.modules.linkpruefer import Linkpruefer
from sn_basis.modules.stilpruefer import Stilpruefer
from sn_basis.modules.Datenschreiber import Datenschreiber
# Raumfilter-Optionen
RAUMFILTER_VAR = "Raumfilter"
RAUMFILTER_OPTIONS = ("Verfahrensgebiet", "Pufferlayer", "ohne")
RAUMFILTER_DEFAULT = "Pufferlayer"
pm = Pruefmanager(ui_modus="qgis")
lp = Linkpruefer()
sp = Stilpruefer()
pm = Pruefmanager(ui_modus="qgis")
lp = Linkpruefer()
sp = Stilpruefer()
class TabA(QWidget):
@@ -62,6 +64,8 @@ class TabA(QWidget):
self.pruefmanager = Pruefmanager(ui_modus="qgis")
# DataGrabber-Instanz (synchroner Aufruf; Prüfungen übernimmt Pruefmanager/Pruefer)
# Hinweis: DataGrabber erwartet ggf. Prüfer-Objekte; hier werden sie nicht übergeben,
# da TabALogic / Pruefmanager diese zur Laufzeit bereitstellen können.
self.data_grabber = DataGrabber(pruefmanager=self.pruefmanager)
# Platzhalter, die vom Plugin oder Nutzer gesetzt werden können
@@ -72,7 +76,7 @@ class TabA(QWidget):
self.lokale_linkliste: Optional[str] = None
# UI-Widget-Referenz für Raumfilter
self._raumfilter_combo: Optional[ComboBox] = None
self._raumfilter_combo: Optional[QComboBox] = None
if build_ui:
self._build_ui()
@@ -164,7 +168,7 @@ class TabA(QWidget):
# Raumfilter-Label + ComboBox (unterhalb der Layer-Auswahl)
main_layout.addWidget(QLabel("Raumfilter"))
self._raumfilter_combo = ComboBox(self)
self._raumfilter_combo = QComboBox(self)
# Fülle Optionen (Wrapper stellt addItems bereit)
try:
self._raumfilter_combo.addItems(list(RAUMFILTER_OPTIONS))
@@ -211,8 +215,14 @@ class TabA(QWidget):
main_layout.addWidget(self._raumfilter_combo)
# Aktion: Fachdaten laden
self.btn_load = QPushButton("Fachdaten laden")
# Neuer Button direkt unterhalb der Raumfilter-Combo: "Fachdaten laden"
self.btn_pipeline = QPushButton("Fachdaten laden")
self.btn_pipeline.setToolTip("Starte Pipeline: Linkliste → DataGrabber → Datenschreiber → Log")
self.btn_pipeline.clicked.connect(self._on_run_pipeline)
main_layout.addWidget(self.btn_pipeline)
# (Optional) bestehender Button weiter unten für alternative Platzierung
self.btn_load = QPushButton("Fachdaten laden (alt)")
self.btn_load.clicked.connect(self._on_load_fachdaten)
main_layout.addWidget(self.btn_load)
@@ -307,11 +317,8 @@ class TabA(QWidget):
def _on_load_fachdaten(self) -> None:
"""
Platzhalter-Handler für 'Fachdaten laden'.
Keine Prüfungen oder Exception-Handling hier. Die fachliche Prüfung
und Fehlerbehandlung erfolgen zur Laufzeit durch den Pruefmanager und
die Prüfer, die vom DataGrabber verwendet werden.
Bestehender, kompakter Handler für 'Fachdaten laden'.
Führt Dateiprüfung und DataGrabber.run aus (wie zuvor).
"""
pfad = self.file_widget.filePath()
@@ -327,13 +334,130 @@ class TabA(QWidget):
except Exception:
zielpfad = ergebnis.kontext
self.data_grabber.run(
attributes_list=self._attributes_list,
pufferlayer=self._pufferlayer,
zielpfad=zielpfad,
temporaer=(ergebnis.aktion == "temporaer_erzeugen"),
temporaer_erlaubt=True,
)
# DataGrabber.run wird wie bisher aufgerufen; Signatur kann variieren.
# Wir übergeben die bekannten Parameter; DataGrabber ist verantwortlich,
# die Linkliste intern zu verwenden (z. B. aus TabALogic oder über Argumente).
try:
self.data_grabber.run(
attributes_list=self._attributes_list,
pufferlayer=self._pufferlayer,
zielpfad=zielpfad,
temporaer=(ergebnis.aktion == "temporaer_erzeugen"),
temporaer_erlaubt=True,
)
except Exception:
# Fehler werden vom Pruefmanager / DataGrabber protokolliert
pass
def _on_run_pipeline(self) -> None:
"""
Neuer, vollständiger Pipeline-Handler, der:
- Dateiprüfung (Verfahrens-DB)
- DataGrabber-Ausführung (mit Linkliste)
- Datenschreiber (schreiben, laden)
- Logschreiber (Log-Datei)
ausführt und Ergebnisse über den Pruefmanager protokolliert.
"""
# 1) Verfahrens-DB prüfen / ermitteln
pfad = self.file_widget.filePath()
pruefer = Dateipruefer(pfad=pfad, temporaer_erlaubt=True)
ergebnis = pruefer.pruefe()
ergebnis = self.pruefmanager.verarbeite(ergebnis)
zielpfad = None
if ergebnis.kontext is not None:
try:
zielpfad = str(ergebnis.kontext)
except Exception:
zielpfad = ergebnis.kontext
if not zielpfad:
# Falls kein Zielpfad ermittelt werden konnte, protokollieren und abbrechen
pe_err = pruef_ergebnis(
ok=False,
meldung="Kein gültiger Speicherort für Verfahrens-DB ermittelt; Pipeline abgebrochen.",
aktion="kein_dateipfad",
kontext={},
)
self.pruefmanager.verarbeite(pe_err)
return
# 2) DataGrabber ausführen
# Erwartung: DataGrabber.run gibt (daten_dict, processed_results) zurück.
# Falls die konkrete Implementierung anders ist, passt dieser Aufruf entsprechend an.
try:
run_result = self.data_grabber.run(
attributes_list=self._attributes_list,
pufferlayer=self._pufferlayer,
zielpfad=zielpfad,
temporaer=(ergebnis.aktion == "temporaer_erzeugen"),
temporaer_erlaubt=True,
)
except Exception as exc:
pe_err = pruef_ergebnis(
ok=False,
meldung=f"DataGrabber-Fehler: {exc}",
aktion="datenabruf",
kontext={},
)
self.pruefmanager.verarbeite(pe_err)
return
# Normalisiere Rückgabe: unterstütze sowohl None, einzelnes dict oder Tuple
daten_dict = {}
processed_results = []
if isinstance(run_result, tuple) and len(run_result) >= 2:
daten_dict, processed_results = run_result[0], run_result[1]
elif isinstance(run_result, dict) and "daten" in run_result:
daten_dict = run_result
# processed_results bleiben leer oder werden vom DataGrabber intern protokolliert
else:
# Wenn run() nichts zurückgibt, versuchen wir, auf DataGrabber intern gespeicherte Ergebnisse zuzugreifen
daten_dict = getattr(self.data_grabber, "last_daten_dict", {}) or {}
processed_results = getattr(self.data_grabber, "last_processed_results", []) or []
# 3) Datenschreiber: Daten in GPKG schreiben
try:
ds = Datenschreiber(pruefmanager=self.pruefmanager, gpkg_path=zielpfad)
layer_infos = ds.schreibe_Daten(daten_dict=daten_dict, processed_results=processed_results, speicherort=zielpfad)
except Exception as exc:
pe_err = pruef_ergebnis(
ok=False,
meldung=f"Fehler beim Schreiben der Daten: {exc}",
aktion="save_exception",
kontext={},
)
self.pruefmanager.verarbeite(pe_err)
return
# 4) Layer laden und Stile anwenden
try:
ds.lade_Layer(layer_infos)
except Exception as exc:
pe_warn = pruef_ergebnis(
ok=True,
meldung=f"Fehler beim Laden der Layer: {exc}",
aktion="layer_nicht_gefunden",
kontext={},
)
self.pruefmanager.verarbeite(pe_warn)
# 5) Log schreiben
try:
log_path = ds.schreibe_log(processed_results=processed_results, speicherort=zielpfad)
# Optional: zeige Erfolgsmeldung
try:
QMessageBox.information(self, "Pipeline abgeschlossen", f"Pipeline erfolgreich abgeschlossen.\nLog: {log_path}")
except Exception:
pass
except Exception as exc:
pe_warn = pruef_ergebnis(
ok=True,
meldung=f"Log konnte nicht geschrieben werden: {exc}",
aktion="standarddatei_vorschlagen",
kontext={},
)
self.pruefmanager.verarbeite(pe_warn)
# ---------------------------------------------------------
# Raumfilter Callback