Vorlagen-Pipeline angelegt (Start bis Prüfung Atlas-Anzahl)
This commit is contained in:
@@ -2,8 +2,11 @@
|
||||
sn_plan41/ui/tab_b_logic.py – Fachlogik für Tab B (Druck)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from sn_basis.functions.variable_wrapper import set_variable
|
||||
import math
|
||||
from sn_basis.functions.variable_wrapper import set_variable, get_variable
|
||||
from sn_basis.functions.qgiscore_wrapper import QgsProject, get_layer_extent
|
||||
from sn_basis.modules.Pruefmanager import Pruefmanager
|
||||
from sn_basis.modules.layerpruefer import Layerpruefer
|
||||
|
||||
|
||||
KARTENNAME_VAR = "sn_kartenname"
|
||||
@@ -81,4 +84,128 @@ class TabBLogic:
|
||||
def set_formfaktor(self, endlosrolle: bool) -> None:
|
||||
"""Setzt ``sn_formfaktor`` auf ``Endlosrolle`` oder ``Blatt``."""
|
||||
set_variable(FORMFAKTOR_VAR, "Endlosrolle" if endlosrolle else "Blatt", scope="project")
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# Pipeline: Druckvorlage_anlegen
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
def druckvorlage_anlegen(
|
||||
self,
|
||||
kartenname_auswahl: str,
|
||||
massstab_auswahl: str,
|
||||
zielgroesse: str,
|
||||
formfaktor: bool,
|
||||
) -> dict:
|
||||
"""Pipeline 'Druckvorlage_anlegen'.
|
||||
|
||||
Prüft Parameter, berechnet Plotgröße und stellt bei Bedarf Atlas-Rückfrage.
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
``ok`` (bool): Ob die Pipeline erfolgreich durchlaufen werden soll.
|
||||
``switch_to_tab_a`` (bool): Ob Tab A aktiviert werden soll.
|
||||
``atlas_seiten`` (int): Anzahl benötigter Seiten (1 = kein Atlas).
|
||||
"""
|
||||
# ─── 1. Verfahrensgebiet-Layer prüfen ─────────────────────────────
|
||||
layer_id = get_variable("tab_a_layer_id", scope="project") or ""
|
||||
layer = None
|
||||
if layer_id:
|
||||
try:
|
||||
layer = QgsProject.instance().mapLayer(layer_id)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
lp = Layerpruefer(layer=layer)
|
||||
ergebnis = lp.pruefe()
|
||||
if not ergebnis.ok:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Verfahrensgebiets-Layer angeben",
|
||||
"Verfahrensgebiets-Layer angeben",
|
||||
)
|
||||
return {"ok": False, "switch_to_tab_a": True, "atlas_seiten": 0}
|
||||
|
||||
set_variable("sn_verfahrensgebietslayer", layer_id, scope="project")
|
||||
|
||||
# ─── 2. Kartenname prüfen ─────────────────────────────────────────
|
||||
if kartenname_auswahl not in (KARTENNAME_38, KARTENNAME_41):
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Kartennamen wählen",
|
||||
"Kartennamen wählen",
|
||||
)
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
|
||||
# ─── 3. Maßstab ermitteln ─────────────────────────────────────────
|
||||
if massstab_auswahl == MASSSTAB_WIE_KARTENFENSTER:
|
||||
massstab_str = get_variable(PLOTMASSSTAB_VAR, scope="project") or ""
|
||||
try:
|
||||
massstab_zahl = float(massstab_str)
|
||||
except (ValueError, TypeError):
|
||||
massstab_zahl = 0.0
|
||||
else:
|
||||
massstab_zahl = float(PLOTMASSSTAB_BY_AUSWAHL.get(massstab_auswahl, 0))
|
||||
|
||||
if massstab_zahl <= 0:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Maßstab fehlt",
|
||||
"Kein gültiger Maßstab angegeben.",
|
||||
)
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
|
||||
# ─── 4. Kartenbild berechnen ──────────────────────────────────────
|
||||
# Der Layer wird als metrisch projiziert (Einheit: m) vorausgesetzt,
|
||||
# wie es für deutsche Planungslagen (z.B. EPSG:25832) üblich ist.
|
||||
extent = get_layer_extent(layer)
|
||||
if extent is None:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Fehler",
|
||||
"Layer-Ausdehnung konnte nicht ermittelt werden.",
|
||||
)
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
|
||||
# Naturgröße (m) → Papiergröße (mm): mm = m * 1000 / massstab
|
||||
kartenbild_w = extent.width() * 1000.0 / massstab_zahl
|
||||
kartenbild_h = extent.height() * 1000.0 / massstab_zahl
|
||||
|
||||
# ─── 5. Plotgröße = Kartenbild + Randabstand (x+210 mm, y+20 mm) ──
|
||||
plotgroesse_w = kartenbild_w + 210.0
|
||||
plotgroesse_h = kartenbild_h + 20.0
|
||||
|
||||
# ─── 6. Zielgröße bestimmen ───────────────────────────────────────
|
||||
din_dims = DIN_GROESSEN.get(zielgroesse, DIN_GROESSEN[DIN_STANDARD])
|
||||
if formfaktor: # Endlosrolle: X-Richtung auf 2000 mm begrenzt
|
||||
ziel_w, ziel_h = 2000.0, float(din_dims[1])
|
||||
else:
|
||||
ziel_w, ziel_h = float(din_dims[0]), float(din_dims[1])
|
||||
|
||||
# ─── 7. Passt auf ein Blatt? ──────────────────────────────────────
|
||||
if plotgroesse_w <= ziel_w and plotgroesse_h <= ziel_h:
|
||||
return {"ok": True, "switch_to_tab_a": False, "atlas_seiten": 1}
|
||||
|
||||
# ─── 8. Atlas: Anzahl Seiten berechnen ────────────────────────────
|
||||
# Nutzbarer Kartenbereich pro Atlasseite (abzüglich gleichem Randabstand)
|
||||
seite_karte_w = ziel_w - 210.0
|
||||
seite_karte_h = ziel_h - 20.0
|
||||
|
||||
if seite_karte_w <= 0 or seite_karte_h <= 0:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Blattgröße zu klein",
|
||||
"Die gewählte Zielgröße ist kleiner als der Mindest-Randabstand. "
|
||||
"Bitte eine größere Blattgröße wählen.",
|
||||
)
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
|
||||
pages_x = math.ceil(kartenbild_w / seite_karte_w)
|
||||
pages_y = math.ceil(kartenbild_h / seite_karte_h)
|
||||
anzahl_seiten = pages_x * pages_y
|
||||
|
||||
ja = self.pruefmanager.frage_ja_nein(
|
||||
"Ausdruck als Atlas anlegen?",
|
||||
f"Für die ausgewählten Parameter sind {anzahl_seiten} Einzelseiten erforderlich.\n"
|
||||
"Ausdruck als Atlas anlegen?",
|
||||
default=True,
|
||||
)
|
||||
if not ja:
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": anzahl_seiten}
|
||||
|
||||
return {"ok": True, "switch_to_tab_a": False, "atlas_seiten": anzahl_seiten}
|
||||
@@ -12,6 +12,7 @@ from sn_basis.functions.qt_wrapper import (
|
||||
QComboBox,
|
||||
QCheckBox,
|
||||
QHBoxLayout,
|
||||
QPushButton,
|
||||
)
|
||||
from sn_basis.functions.qgiscore_wrapper import QgsProject
|
||||
from sn_basis.functions.qgisui_wrapper import iface
|
||||
@@ -77,8 +78,8 @@ class TabB(QWidget):
|
||||
self._connected_theme_collection: object = None # Referenz für sauberes Trennen
|
||||
self._zielgroesse_combo: Optional[QComboBox] = None
|
||||
self._endlosrolle_cb: Optional[QCheckBox] = None
|
||||
self._btn_vorlage_erstellen: Optional[QPushButton] = None
|
||||
|
||||
|
||||
self._build_ui()
|
||||
self._restore_state()
|
||||
self._connect_theme_collection_signals()
|
||||
@@ -158,6 +159,10 @@ class TabB(QWidget):
|
||||
zielgroesse_row.addWidget(self._endlosrolle_cb)
|
||||
main_layout.addLayout(zielgroesse_row)
|
||||
|
||||
self._btn_vorlage_erstellen = QPushButton("Vorlage erstellen", self)
|
||||
self._btn_vorlage_erstellen.clicked.connect(self._on_vorlage_erstellen)
|
||||
main_layout.addWidget(self._btn_vorlage_erstellen)
|
||||
|
||||
main_layout.addStretch(1)
|
||||
self.setLayout(main_layout)
|
||||
|
||||
@@ -236,6 +241,34 @@ class TabB(QWidget):
|
||||
if self.logic:
|
||||
self.logic.set_formfaktor(checked)
|
||||
|
||||
def _on_vorlage_erstellen(self) -> None:
|
||||
"""Startet die Pipeline Druckvorlage_anlegen."""
|
||||
if not self.logic or not self.pruefmanager:
|
||||
return
|
||||
|
||||
result = self.logic.druckvorlage_anlegen(
|
||||
kartenname_auswahl=self._kartenname_combo.currentText() if self._kartenname_combo else "",
|
||||
massstab_auswahl=self._massstab_combo.currentText() if self._massstab_combo else "",
|
||||
zielgroesse=self._zielgroesse_combo.currentText() if self._zielgroesse_combo else DIN_STANDARD,
|
||||
formfaktor=self._endlosrolle_cb.isChecked() if self._endlosrolle_cb else False,
|
||||
)
|
||||
|
||||
if result.get("switch_to_tab_a"):
|
||||
self._aktiviere_tab_a()
|
||||
|
||||
def _aktiviere_tab_a(self) -> None:
|
||||
"""Wechselt zum Tab A im übergeordneten TabWidget."""
|
||||
try:
|
||||
widget = self.parent()
|
||||
while widget is not None:
|
||||
if hasattr(widget, "setCurrentIndex") and hasattr(widget, "count"):
|
||||
widget.setCurrentIndex(0)
|
||||
return
|
||||
parent_fn = getattr(widget, "parent", None)
|
||||
widget = parent_fn() if callable(parent_fn) else None
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _connect_project_signals(self) -> None:
|
||||
"""Verbindet QgsProject-Signale für Projektwechsel/-neuladen."""
|
||||
project = QgsProject.instance()
|
||||
|
||||
Reference in New Issue
Block a user