""" sn_plan41/ui/layout.py – Aufbau von Drucklayouts für Plan41. """ from __future__ import annotations import math from typing import Any from sn_basis.functions.qt_wrapper import QFont from sn_basis.functions.qgiscore_wrapper import ( QgsLayoutItem, QgsLayoutItemLabel, QgsLayoutItemMap, QgsLayoutPoint, QgsLayoutSize, QgsPrintLayout, QgsProject, QgsUnitTypes, ) from sn_basis.functions.qgisui_wrapper import open_layout_designer MM = QgsUnitTypes.LayoutMillimeters class Layout: """Erzeugt ein QGIS-Layout für den Druck.""" def __init__(self, project: Any | None = None) -> None: self.project = project or QgsProject.instance() def create_single_page_layout( self, name: str, page_width_mm: float, page_height_mm: float, map_width_mm: float, map_height_mm: float, extent: Any, plotmassstab: float, thema: str = "", ) -> Any: """Erzeugt ein einseitiges Layout und öffnet es im Designer.""" print(f"[Layout] create_single_page_layout: name='{name}', " f"page=({page_width_mm}x{page_height_mm}), map=({map_width_mm:.1f}x{map_height_mm:.1f}), " f"massstab={plotmassstab}, thema='{thema}'") layout_manager = self.project.layoutManager() print(f"[Layout] layoutManager: {layout_manager!r}") existing_layout = layout_manager.layoutByName(name) if existing_layout is not None: raise ValueError(f"Eine Vorlage mit der Bezeichnung '{name}' existiert bereits.") layout = QgsPrintLayout(self.project) layout.initializeDefaults() layout.setName(name) print(f"[Layout] QgsPrintLayout erstellt: {layout!r}") page = layout.pageCollection().page(0) page.setPageSize(QgsLayoutSize(page_width_mm, page_height_mm, MM)) print(f"[Layout] Seitengröße gesetzt: {page_width_mm}x{page_height_mm} mm") hauptkarte = QgsLayoutItemMap(layout) hauptkarte.setId("Hauptkarte") set_rect = getattr(hauptkarte, "setRect", None) if callable(set_rect): set_rect(0.0, 0.0, map_width_mm, map_height_mm) hauptkarte.attemptMove(QgsLayoutPoint(10.0, 10.0, MM)) hauptkarte.attemptResize(QgsLayoutSize(map_width_mm, map_height_mm, MM)) x_min = getattr(extent, "xMinimum", lambda: float("nan"))() y_min = getattr(extent, "yMinimum", lambda: float("nan"))() x_max = getattr(extent, "xMaximum", lambda: float("nan"))() y_max = getattr(extent, "yMaximum", lambda: float("nan"))() print(f"[Layout] Extent input: xmin={x_min}, ymin={y_min}, xmax={x_max}, ymax={y_max}") hauptkarte.setExtent(extent) if isinstance(plotmassstab, (int, float)) and math.isfinite(plotmassstab) and plotmassstab > 0: hauptkarte.setScale(plotmassstab) else: print(f"[Layout] WARN: ungültiger plotmassstab={plotmassstab!r}, setScale übersprungen") print(f"[Layout] Hauptkarte angelegt: pos=(10,10), size=({map_width_mm:.1f}x{map_height_mm:.1f})") if thema and thema != "aktuell": follow_theme = getattr(hauptkarte, "setFollowVisibilityPreset", None) set_theme_name = getattr(hauptkarte, "setFollowVisibilityPresetName", None) if callable(follow_theme): follow_theme(True) if callable(set_theme_name): set_theme_name(thema) print(f"[Layout] Kartenthema gesetzt: '{thema}'") layout.addLayoutItem(hauptkarte) print("[Layout] Hauptkarte zum Layout hinzugefügt") quellenangabe = QgsLayoutItemLabel(layout) quellenangabe.setId("Quellenangabe") quellenangabe.setText( "Quelle Geobasisdaten: GeoSN, " "dl-de/by-2-0

" "Quelle Fachdaten: Darstellung auf der Grundlage von Daten und mit Erlaubnis des " "Sächsischen Landesamtes für Umwelt, Landwirtschaft und Geologie

" "Basemap:

" "© GeoBasis-DE / BKG ([%year($now)%]) " "CC BY 4.0 " "mit teilweise angepasster Signatur
" ) set_mode = getattr(quellenangabe, "setMode", None) mode_html = getattr(QgsLayoutItemLabel, "ModeHtml", None) print(f"[Layout] QgsLayoutItemLabel.ModeHtml={mode_html!r}") if callable(set_mode) and mode_html is not None: set_mode(mode_html) quellenangabe.setFont(QFont("Arial", 12)) set_reference_point = getattr(quellenangabe, "setReferencePoint", None) lower_left = getattr(getattr(QgsLayoutItem, "ReferencePoint", object), "LowerLeft", None) print(f"[Layout] QgsLayoutItem.ReferencePoint.LowerLeft={lower_left!r}") if callable(set_reference_point) and lower_left is not None: set_reference_point(lower_left) quellenangabe.attemptMove(QgsLayoutPoint(map_width_mm + 30.0, page_height_mm - 120.0, MM)) quellenangabe.attemptResize(QgsLayoutSize(180.0, 100.0, MM)) layout.addLayoutItem(quellenangabe) print("[Layout] Quellenangabe zum Layout hinzugefügt") layout_manager.addLayout(layout) print("[Layout] Layout zum LayoutManager hinzugefügt") open_layout_designer(layout) print("[Layout] Layout Designer geöffnet") return layout