Files
Plugin_SN_Plan41/ui/layout.py

126 lines
5.4 KiB
Python
Raw Normal View History

"""
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, "
"<a href=\"https://www.govdata.de/dl-de/by-2-0\">dl-de/by-2-0</a><br><br>"
"Quelle Fachdaten: Darstellung auf der Grundlage von Daten und mit Erlaubnis des "
"Sächsischen Landesamtes für Umwelt, Landwirtschaft und Geologie<br><br>"
"Basemap:<br><br>"
"© GeoBasis-DE / <a href=\"https://www.bkg.bund.de\">BKG</a> ([%year($now)%]) "
"<a href=\"https://creativecommons.org/licences/by/4.0/\">CC BY 4.0</a> "
"mit teilweise angepasster Signatur<br>"
)
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