Baufreigabe-Layout fix auf A3/A4

This commit is contained in:
2026-04-10 23:26:58 +02:00
parent 0900c6d3b0
commit 7ad8ba054f
3 changed files with 169 additions and 67 deletions
+64 -33
View File
@@ -10,7 +10,6 @@ in der PrintLogic.
"""
from __future__ import annotations
import math
from typing import Any
from sn_basis.functions.qt_wrapper import QFont
@@ -33,11 +32,12 @@ MM = QgsUnitTypes.LayoutMillimeters
class PrintLayoutBaufreigabe(PrintLayout):
"""Erzeugt QGIS-Einzelblatt-Layouts mit fester DIN A3/A4 Querformat-Groesse und 120mm Kartenschild."""
"""Erzeugt QGIS-Einzelblatt-Layouts mit fester DIN A3/A4 Querformat-Groesse und 80mm Kartenschild."""
_FRAME_STROKE_WIDTH_MM = 0.5
_KARTENSCHILD_WIDTH_MM = 120.0 # Unterschied zu StandardLayout: 120mm statt 180mm
_KARTENSCHILD_WIDTH_MM = 80.0
_KARTENSCHILD_HEIGHT_MM = 92.0
_ATLAS_FRAME_MARGIN_MM = 10.0
_GRID_INTERVAL_MAP_UNITS = 500.0
# DIN-Formate: nur A3 und A4 im Querformat
@@ -55,7 +55,7 @@ class PrintLayoutBaufreigabe(PrintLayout):
"quellenangabe": {
"id": "Quellenangabe",
"object_name": "Quellenangabe",
"size_mm": (120.0, 100.0), # Breite angepasst auf 120mm Kartenschild
"size_mm": (80.0, 100.0),
"format": "Format_1",
},
"textfeld": {
@@ -69,7 +69,7 @@ class PrintLayoutBaufreigabe(PrintLayout):
"legende": {
"id": "Legende",
"object_name": "Legende",
"size_mm": (120.0, 60.0), # Breite angepasst auf 120mm Kartenschild
"size_mm": (80.0, 60.0),
},
}
@@ -108,7 +108,7 @@ class PrintLayoutBaufreigabe(PrintLayout):
extent: QgsRectangle der Kartenausdehnung
plotmassstab: Plotmassstab (z.B. 5000 fuer 1:5000)
thema: Name des Visibility-Presets (optional)
fit_extent_to_map: Ob das Extent an die Kartengroe angepasst wird
fit_extent_to_map: Wird fuer Baufreigabe ignoriert (feste Kartenflaeche)
Returns:
QgsPrintLayout objektInstance (wird im Layout-Dialog geoeffnet)
@@ -152,21 +152,45 @@ class PrintLayoutBaufreigabe(PrintLayout):
map_height_mm,
)
fitted_extent = extent
if fit_extent_to_map:
fitted_extent = self._fit_extent_to_map_item(extent, map_width_mm, map_height_mm)
if fitted_extent is not None and hasattr(fitted_extent, "isNull") and callable(fitted_extent.isNull) and not fitted_extent.isNull():
_ = fit_extent_to_map
if extent is not None and hasattr(extent, "isNull") and callable(extent.isNull) and not extent.isNull():
try:
hauptkarte.setExtent(fitted_extent)
hauptkarte.zoomToExtent(extent)
except Exception:
pass
if isinstance(plotmassstab, (int, float)) and math.isfinite(plotmassstab) and plotmassstab > 0:
if isinstance(plotmassstab, (int, float)) and plotmassstab > 0:
try:
hauptkarte.setScale(plotmassstab)
except Exception:
pass
# Hauptkarte standardmaessig Atlas-gesteuert:
# - Extent folgt aktuellem Atlas-Objekt
# - Skalierung automatisch
# - Margin entspricht ca. 1 cm Rand innerhalb der Kartenflaeche
set_atlas_driven = getattr(hauptkarte, "setAtlasDriven", None)
if callable(set_atlas_driven):
try:
set_atlas_driven(True)
except Exception:
pass
set_atlas_scaling_mode = getattr(hauptkarte, "setAtlasScalingMode", None)
atlas_mode_auto = getattr(getattr(QgsLayoutItemMap, "AtlasScalingMode", object), "Auto", None)
if callable(set_atlas_scaling_mode) and atlas_mode_auto is not None:
try:
set_atlas_scaling_mode(atlas_mode_auto)
except Exception:
pass
set_atlas_margin = getattr(hauptkarte, "setAtlasMargin", None)
if callable(set_atlas_margin):
try:
set_atlas_margin(self._calc_atlas_margin_percent(map_width_mm, map_height_mm))
except Exception:
pass
set_frame_enabled = getattr(hauptkarte, "setFrameEnabled", None)
if callable(set_frame_enabled):
try:
@@ -237,7 +261,7 @@ class PrintLayoutBaufreigabe(PrintLayout):
) -> None:
"""Erstellt Legende, Quellenangabe und Kartenschild fuer Baufreigabe-Layout.
Angepasst fuer 120mm Kartenschild statt 180mm, mit proportional skalierten Textfeldern.
Angepasst fuer 80mm Kartenschild statt 180mm.
"""
if self._current_layout is None:
raise RuntimeError("Kein Layout aktiv.")
@@ -248,7 +272,7 @@ class PrintLayoutBaufreigabe(PrintLayout):
kartenfenster_untere_rechte_ecke_mm[1] + rel_y_mm,
)
# Legende: 120mm Breite (angepasst), hoehe adaptive wie Standard
# Legende: 80mm Breite, hoehe adaptive wie Standard
legende_x = kartenfenster_untere_rechte_ecke_mm[0] + 10.0
legende_height_mm = max(map_height_mm - 122.0, 20.0)
legende_y = map_top_mm
@@ -270,7 +294,7 @@ class PrintLayoutBaufreigabe(PrintLayout):
equal_column_width=False,
)
# Quellenangabe: 120mm Breite
# Quellenangabe: 80mm Breite
quellenangabe_x, quellenangabe_y = _coords_rel_untere_rechte_ecke(10.0, -102.0)
quellenangabe_hoehe_mm = 20.0
quellenangabe_obere_y = quellenangabe_y - quellenangabe_hoehe_mm
@@ -296,7 +320,7 @@ class PrintLayoutBaufreigabe(PrintLayout):
object_name="Quellenangabe",
)
# Kartenschild: 120mm Breite (angepasst)
# Kartenschild: 80mm Breite
kartenschild_x, kartenschild_y = _coords_rel_untere_rechte_ecke(10.0, 0.0)
self._create_rectangle_box_item(
self._current_layout,
@@ -323,32 +347,29 @@ class PrintLayoutBaufreigabe(PrintLayout):
stroke_width_mm=0.1,
)
# Textfelder im Kartenschild: proportional skaliert auf 120mm
# Skalierungsfaktor: 120/180 = 0.667 fuer horizontale Abstaende/Breiten
scale_x = self._KARTENSCHILD_WIDTH_MM / 180.0
base_x = 16.0 * scale_x # ~10.7mm statt 16mm
label_width_scaled = 101.0 * scale_x # ~67.3mm statt 101mm
# Textfelder im Kartenschild ohne Skalierungslogik.
# Positionen werden bewusst als feste Werte gesetzt und bei Bedarf manuell angepasst.
labels = [
("[% @sn_amt %]", base_x, -84.0, label_width_scaled, 4.0, "Format_1", "Herausgeber"),
("[% @sn_bezeichnung %]", base_x, -75.0, label_width_scaled, 4.0, "Format_1", "Bezeichnung_Flurbereinigung"),
("[% @sn_name %]", base_x, -64.0, label_width_scaled, 5.0, "Format_2", "Name_Flurbereinigung"),
("[% @sn_gemeinden %]", base_x, -56.0, label_width_scaled, 4.0, "Format_1", "Stadt_Gemeinde"),
("[% @sn_landkreise_proj %]", base_x, -48.0, label_width_scaled, 4.0, "Format_1", "Landkreis"),
("[% @sn_kartenname %]", base_x, -32.0, label_width_scaled - 30, 12.0, "Format_3", "Kartenname"),
("Gefertigt: ", base_x, -23.0, 40.0 * scale_x, 4.0, "Format_1", "Gefertigt"),
("Geprueft: ", base_x + 40.0 * scale_x + 5.0, -23.0, 40.0 * scale_x, 4.0, "Format_1", "Geprueft"),
("[% @sn_amt %]", 16.0, -84.0, 171.0, 4.0, "Format_1", "Herausgeber"),
("[% @sn_bezeichnung %]", 16.0, -75.0, 171.0, 4.0, "Format_1", "Bezeichnung_Flurbereinigung"),
("[% @sn_name %]", 16.0, -64.0, 171.0, 5.0, "Format_2", "Name_Flurbereinigung"),
("[% @sn_gemeinden %]", 16.0, -56.0, 171.0, 4.0, "Format_1", "Stadt_Gemeinde"),
("[% @sn_landkreise_proj %]", 16.0, -48.0, 171.0, 4.0, "Format_1", "Landkreis"),
("[% @sn_kartenname %]", 16.0, -32.0, 137.0, 12.0, "Format_3", "Kartenname"),
("Gefertigt: ", 16.0, -23.0, 81.0, 4.0, "Format_1", "Gefertigt"),
("Geprueft: ", 101.0, -23.0, 81.0, 4.0, "Format_1", "Geprueft"),
(
"Massstab: 1 : [%round(map_get(item_variables('Hauptkarte'),'map_scale'),0)%]",
base_x,
16.0,
-13.0,
40.0 * scale_x,
81.0,
4.0,
"Format_1",
"Massstab",
),
("Ausgabedatum: [%format_date(now(), 'dd.MM.yyyy')%]", base_x + 40.0 * scale_x + 5.0, -13.0, 40.0 * scale_x, 4.0, "Format_1", "Ausgabedatum"),
("Aktenzeichen: ", base_x, -3.0, label_width_scaled, 4.0, "Format_1", "Aktenzeichen"),
("Ausgabedatum: [%format_date(now(), 'dd.MM.yyyy')%]", 101.0, -13.0, 81.0, 4.0, "Format_1", "Ausgabedatum"),
("Aktenzeichen: ", 16.0, -3.0, 171.0, 4.0, "Format_1", "Aktenzeichen"),
]
for text, rx, ry, w, h, fmt, obj_name in labels:
@@ -363,3 +384,13 @@ class PrintLayoutBaufreigabe(PrintLayout):
expression_enabled=True,
object_name=obj_name,
)
def _calc_atlas_margin_percent(self, map_width_mm: float, map_height_mm: float) -> float:
"""Berechnet Atlas-Margin in Prozent, sodass etwa 10 mm Rand sichtbar bleiben."""
margin_mm = self._ATLAS_FRAME_MARGIN_MM
if map_width_mm <= 2 * margin_mm or map_height_mm <= 2 * margin_mm:
return 5.0
p_width = (100.0 * margin_mm) / (map_width_mm - 2.0 * margin_mm)
p_height = (100.0 * margin_mm) / (map_height_mm - 2.0 * margin_mm)
return max(p_width, p_height)