forked from Daniel/Plugin_SN_Plan41
Altlasfunktion eingebaut (wenn plotgröße größer als Zielformat)
This commit is contained in:
230
ui/layout.py
230
ui/layout.py
@@ -199,3 +199,233 @@ class Layout:
|
||||
open_layout_designer(layout)
|
||||
print("[Layout] Layout Designer geöffnet")
|
||||
return layout
|
||||
|
||||
def create_atlas_layout(
|
||||
self,
|
||||
name: str,
|
||||
page_width_mm: float,
|
||||
page_height_mm: float,
|
||||
map_width_mm: float,
|
||||
map_height_mm: float,
|
||||
extent: Any,
|
||||
plotmassstab: float,
|
||||
atlas_layer: Any,
|
||||
thema: str = "",
|
||||
) -> Any:
|
||||
"""Erzeugt ein Atlas-Layout mit Coverage-Layer ``Atlasobjekte``."""
|
||||
layout_manager = self.project.layoutManager()
|
||||
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)
|
||||
|
||||
page = layout.pageCollection().page(0)
|
||||
page.setPageSize(QgsLayoutSize(page_width_mm, page_height_mm, MM))
|
||||
# Verifiziere, dass QGIS die Größe akzeptiert hat
|
||||
page_size = page.pageSize() if hasattr(page, 'pageSize') else None
|
||||
if page_size is not None and hasattr(page_size, 'width'):
|
||||
actual_w = float(page_size.width())
|
||||
actual_h = float(page_size.height())
|
||||
print(f"[Layout] Atlas Page gesetzt: x=0, y=0, width={page_width_mm:.1f}mm→{actual_w:.1f}mm, height={page_height_mm:.1f}mm→{actual_h:.1f}mm")
|
||||
else:
|
||||
print(f"[Layout] Atlas Page: x=0, y=0, width={page_width_mm:.1f}mm, height={page_height_mm:.1f}mm")
|
||||
|
||||
map_left_mm = 10.0
|
||||
map_top_mm = 10.0
|
||||
map_right_mm = map_left_mm + map_width_mm
|
||||
map_bottom_mm = map_top_mm + map_height_mm
|
||||
|
||||
hauptkarte = QgsLayoutItemMap(layout)
|
||||
hauptkarte.setId("Hauptkarte")
|
||||
layout.addLayoutItem(hauptkarte)
|
||||
hauptkarte.attemptMove(QgsLayoutPoint(map_left_mm, map_top_mm, MM))
|
||||
hauptkarte.attemptResize(QgsLayoutSize(map_width_mm, map_height_mm, MM))
|
||||
|
||||
# Verifiziere mit Units-bewussten Methoden (rect() kann andere Units verwenden).
|
||||
actual_w = None
|
||||
actual_h = None
|
||||
actual_x = None
|
||||
actual_y = None
|
||||
|
||||
# Versuche zuerst, die Größe mit Unit-Methoden zu lesen
|
||||
try:
|
||||
if hasattr(hauptkarte, 'sizeWithUnits'):
|
||||
size_item = hauptkarte.sizeWithUnits()
|
||||
if hasattr(size_item, 'width') and hasattr(size_item, 'height'):
|
||||
actual_w = float(size_item.width())
|
||||
actual_h = float(size_item.height())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
if hasattr(hauptkarte, 'positionWithUnits'):
|
||||
pos_item = hauptkarte.positionWithUnits()
|
||||
if hasattr(pos_item, 'x') and hasattr(pos_item, 'y'):
|
||||
actual_x = float(pos_item.x())
|
||||
actual_y = float(pos_item.y())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Fallback: nutze rect() und teile durch UnitFaktor, falls nötig
|
||||
if actual_w is None or actual_h is None:
|
||||
try:
|
||||
actual_rect = hauptkarte.rect()
|
||||
if actual_rect is not None:
|
||||
actual_w = float(actual_rect.width())
|
||||
actual_h = float(actual_rect.height())
|
||||
actual_x = float(actual_rect.x())
|
||||
actual_y = float(actual_rect.y())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if actual_w is not None and actual_h is not None:
|
||||
print(f"[Layout] Atlas Hauptkarte gesetzt: x={map_left_mm:.1f}mm→{actual_x:.1f}mm, y={map_top_mm:.1f}mm→{actual_y:.1f}mm, width={map_width_mm:.1f}mm→{actual_w:.1f}mm, height={map_height_mm:.1f}mm→{actual_h:.1f}mm")
|
||||
else:
|
||||
print(f"[Layout] Atlas Hauptkarte: x={map_left_mm:.1f}mm, y={map_top_mm:.1f}mm, width={map_width_mm:.1f}mm, height={map_height_mm:.1f}mm")
|
||||
|
||||
if extent is not None and hasattr(extent, "isNull") and callable(extent.isNull) and not extent.isNull():
|
||||
try:
|
||||
hauptkarte.setExtent(extent)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if isinstance(plotmassstab, (int, float)) and math.isfinite(plotmassstab) and plotmassstab > 0:
|
||||
try:
|
||||
hauptkarte.setScale(plotmassstab)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
set_frame_enabled = getattr(hauptkarte, "setFrameEnabled", None)
|
||||
if callable(set_frame_enabled):
|
||||
try:
|
||||
set_frame_enabled(True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
set_frame_stroke_width = getattr(hauptkarte, "setFrameStrokeWidth", None)
|
||||
if callable(set_frame_stroke_width):
|
||||
try:
|
||||
set_frame_stroke_width(0.5)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if thema and thema != "aktuell":
|
||||
follow_theme = getattr(hauptkarte, "setFollowVisibilityPreset", None)
|
||||
set_theme_name = getattr(hauptkarte, "setFollowVisibilityPresetName", None)
|
||||
if callable(follow_theme):
|
||||
try:
|
||||
follow_theme(True)
|
||||
except Exception:
|
||||
pass
|
||||
if callable(set_theme_name):
|
||||
try:
|
||||
set_theme_name(thema)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
set_atlas_driven = getattr(hauptkarte, "setAtlasDriven", None)
|
||||
if callable(set_atlas_driven):
|
||||
try:
|
||||
set_atlas_driven(True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Fester Atlas-Maßstab: plotmassstab bleibt unverändert.
|
||||
set_scaling_mode = getattr(hauptkarte, "setAtlasScalingMode", None)
|
||||
if callable(set_scaling_mode):
|
||||
fixed_mode = getattr(QgsLayoutItemMap, "Fixed", None)
|
||||
if fixed_mode is not None:
|
||||
try:
|
||||
set_scaling_mode(fixed_mode)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
set_atlas_margin = getattr(hauptkarte, "setAtlasMargin", None)
|
||||
if callable(set_atlas_margin):
|
||||
try:
|
||||
set_atlas_margin(0.0)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
set_keep_layer_set = getattr(hauptkarte, "setKeepLayerSet", None)
|
||||
if callable(set_keep_layer_set):
|
||||
try:
|
||||
set_keep_layer_set(True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Sicherheit: Größe nochmal nach Atlas-Konfiguration setzen, um sicherzustellen, dass sie nicht von der Atlas-Einstellung überschrieben wurde.
|
||||
hauptkarte.attemptResize(QgsLayoutSize(map_width_mm, map_height_mm, MM))
|
||||
print(f"[Layout] Atlas Hauptkarte Größe nach Atlas-Konfiguration erneut gesetzt: {map_width_mm:.1f}mm × {map_height_mm:.1f}mm")
|
||||
|
||||
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)
|
||||
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)
|
||||
if callable(set_reference_point) and lower_left is not None:
|
||||
set_reference_point(lower_left)
|
||||
quellenangabe.attemptMove(QgsLayoutPoint(map_right_mm + 5.0, map_bottom_mm, MM))
|
||||
quellenangabe.attemptResize(QgsLayoutSize(180.0, 100.0, MM))
|
||||
layout.addLayoutItem(quellenangabe)
|
||||
|
||||
seitenzahl_label = QgsLayoutItemLabel(layout)
|
||||
seitenzahl_label.setId("Seitenzahl")
|
||||
seitenzahl_label.setFont(QFont("Arial", 12))
|
||||
set_expr_enabled = getattr(seitenzahl_label, "setExpressionEnabled", None)
|
||||
if callable(set_expr_enabled):
|
||||
try:
|
||||
set_expr_enabled(True)
|
||||
except Exception:
|
||||
pass
|
||||
# Ausdrucksauswertung robust über [% ... %]-Platzhalter.
|
||||
seitenzahl_label.setText(
|
||||
"Seite [% attribute(@atlas_feature, 'Seitenzahl') %] von [% @atlas_totalfeatures %]"
|
||||
)
|
||||
set_reference_point = getattr(seitenzahl_label, "setReferencePoint", None)
|
||||
lower_left = getattr(getattr(QgsLayoutItem, "ReferencePoint", object), "LowerLeft", None)
|
||||
if callable(set_reference_point) and lower_left is not None:
|
||||
set_reference_point(lower_left)
|
||||
seitenzahl_label.attemptMove(QgsLayoutPoint(map_right_mm + 5.0, map_bottom_mm - 2.0, MM))
|
||||
seitenzahl_label.attemptResize(QgsLayoutSize(60.0, 8.0, MM))
|
||||
layout.addLayoutItem(seitenzahl_label)
|
||||
|
||||
atlas = layout.atlas()
|
||||
if atlas is not None:
|
||||
set_enabled = getattr(atlas, "setEnabled", None)
|
||||
set_coverage = getattr(atlas, "setCoverageLayer", None)
|
||||
set_hide_coverage = getattr(atlas, "setHideCoverage", None)
|
||||
set_filter_features = getattr(atlas, "setFilterFeatures", None)
|
||||
set_page_name = getattr(atlas, "setPageNameExpression", None)
|
||||
|
||||
if callable(set_enabled):
|
||||
set_enabled(True)
|
||||
if callable(set_coverage):
|
||||
set_coverage(atlas_layer)
|
||||
if callable(set_hide_coverage):
|
||||
set_hide_coverage(True)
|
||||
if callable(set_filter_features):
|
||||
set_filter_features(False)
|
||||
if callable(set_page_name):
|
||||
set_page_name("attribute(@atlas_feature, 'Seitenzahl')")
|
||||
|
||||
layout_manager.addLayout(layout)
|
||||
open_layout_designer(layout)
|
||||
return layout
|
||||
|
||||
@@ -3,8 +3,20 @@ sn_plan41/ui/tab_b_logic.py – Fachlogik für Tab B (Druck)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import math
|
||||
from typing import Any
|
||||
|
||||
from sn_basis.functions.qt_wrapper import QVariant
|
||||
from sn_basis.functions.variable_wrapper import set_variable, get_variable
|
||||
from sn_basis.functions.qgiscore_wrapper import get_layer_extent
|
||||
from sn_basis.functions.qgiscore_wrapper import (
|
||||
QgsProject,
|
||||
QgsVectorLayer,
|
||||
QgsGeometry,
|
||||
QgsFeature,
|
||||
QgsField,
|
||||
QgsVectorFileWriter,
|
||||
)
|
||||
from sn_basis.functions.sys_wrapper import get_plugin_root, join_path, file_exists
|
||||
from sn_basis.modules.Pruefmanager import Pruefmanager
|
||||
from sn_basis.modules.layerpruefer import Layerpruefer
|
||||
from sn_plan41.ui.layout import Layout
|
||||
@@ -53,6 +65,140 @@ class TabBLogic:
|
||||
def __init__(self, pruefmanager: Pruefmanager) -> None:
|
||||
self.pruefmanager = pruefmanager
|
||||
|
||||
@staticmethod
|
||||
def _wkt_rect(x_min: float, y_min: float, x_max: float, y_max: float) -> str:
|
||||
return (
|
||||
f"POLYGON(({x_min} {y_min}, {x_max} {y_min}, {x_max} {y_max}, "
|
||||
f"{x_min} {y_max}, {x_min} {y_min}))"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _set_topological_editing_enabled() -> None:
|
||||
project = QgsProject.instance()
|
||||
set_topological = getattr(project, "setTopologicalEditing", None)
|
||||
if callable(set_topological):
|
||||
try:
|
||||
set_topological(True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def _apply_atlas_style(layer: Any) -> None:
|
||||
style_path = join_path(get_plugin_root(), "sn_plan41", "assets", "atlasobjekte.qml")
|
||||
if not file_exists(style_path):
|
||||
return
|
||||
try:
|
||||
ok, _ = layer.loadNamedStyle(str(style_path))
|
||||
if ok:
|
||||
getattr(layer, "triggerRepaint", lambda: None)()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _create_atlasobjekte_layer(
|
||||
self,
|
||||
layer: Any,
|
||||
extent: Any,
|
||||
pages_x: int,
|
||||
pages_y: int,
|
||||
seite_karte_w: float,
|
||||
seite_karte_h: float,
|
||||
massstab_zahl: float,
|
||||
) -> Any | None:
|
||||
layer_crs = layer.crs() if hasattr(layer, "crs") else None
|
||||
crs_authid = layer_crs.authid() if layer_crs is not None and hasattr(layer_crs, "authid") else "EPSG:25832"
|
||||
atlas_layer = QgsVectorLayer(f"Polygon?crs={crs_authid}", "Atlasobjekte", "memory")
|
||||
if not atlas_layer or not atlas_layer.isValid():
|
||||
return None
|
||||
|
||||
provider = atlas_layer.dataProvider()
|
||||
provider.addAttributes([
|
||||
QgsField("Seitenzahl", QVariant.Int),
|
||||
])
|
||||
atlas_layer.updateFields()
|
||||
|
||||
tile_w_m = seite_karte_w * massstab_zahl / 1000.0
|
||||
tile_h_m = seite_karte_h * massstab_zahl / 1000.0
|
||||
|
||||
x_min = extent.xMinimum()
|
||||
y_min = extent.yMinimum()
|
||||
x_max = extent.xMaximum()
|
||||
y_max = extent.yMaximum()
|
||||
|
||||
seitenzahl = 1
|
||||
features = []
|
||||
for row_idx in range(pages_y):
|
||||
tile_y_max = y_max - row_idx * tile_h_m
|
||||
tile_y_min = tile_y_max - tile_h_m
|
||||
|
||||
for col_idx in range(pages_x):
|
||||
tile_x_min = x_min + col_idx * tile_w_m
|
||||
tile_x_max = tile_x_min + tile_w_m
|
||||
|
||||
tile_geom = QgsGeometry.fromWkt(
|
||||
self._wkt_rect(tile_x_min, tile_y_min, tile_x_max, tile_y_max)
|
||||
)
|
||||
|
||||
feat = QgsFeature(atlas_layer.fields())
|
||||
feat.setGeometry(tile_geom)
|
||||
feat["Seitenzahl"] = seitenzahl
|
||||
features.append(feat)
|
||||
seitenzahl += 1
|
||||
|
||||
if not features:
|
||||
return None
|
||||
|
||||
provider.addFeatures(features)
|
||||
atlas_layer.updateExtents()
|
||||
self._set_topological_editing_enabled()
|
||||
|
||||
verfahrens_db = get_variable("verfahrens_db", scope="project") or ""
|
||||
print(f"[TabBLogic] Atlasobjekte: verfahrens_db='{verfahrens_db}'")
|
||||
if not verfahrens_db:
|
||||
QgsProject.instance().addMapLayer(atlas_layer)
|
||||
self._apply_atlas_style(atlas_layer)
|
||||
print("[TabBLogic] Atlasobjekte temporär ins Projekt geladen")
|
||||
return atlas_layer
|
||||
|
||||
opts = QgsVectorFileWriter.SaveVectorOptions()
|
||||
opts.driverName = "GPKG"
|
||||
opts.fileEncoding = "UTF-8"
|
||||
opts.layerName = "Atlasobjekte"
|
||||
if file_exists(verfahrens_db):
|
||||
opts.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
|
||||
else:
|
||||
opts.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteFile
|
||||
|
||||
err_result = QgsVectorFileWriter.writeAsVectorFormatV3(
|
||||
atlas_layer,
|
||||
verfahrens_db,
|
||||
QgsProject.instance().transformContext(),
|
||||
opts,
|
||||
)
|
||||
|
||||
# QGIS-Versionen liefern hier entweder nur WriterError
|
||||
# oder ein Tupel (WriterError, msg, newPath, layerName).
|
||||
err_code = err_result[0] if isinstance(err_result, tuple) else err_result
|
||||
if err_code != QgsVectorFileWriter.NoError:
|
||||
print(f"[TabBLogic] Atlasobjekte schreiben fehlgeschlagen: err={err_result}")
|
||||
return None
|
||||
|
||||
for existing in QgsProject.instance().mapLayersByName("Atlasobjekte"):
|
||||
try:
|
||||
QgsProject.instance().removeMapLayer(existing.id())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
uri = f"{verfahrens_db}|layername=Atlasobjekte"
|
||||
loaded_layer = QgsVectorLayer(uri, "Atlasobjekte", "ogr")
|
||||
if not loaded_layer or not loaded_layer.isValid():
|
||||
print(f"[TabBLogic] Atlasobjekte laden aus GPKG fehlgeschlagen: uri='{uri}'")
|
||||
return None
|
||||
|
||||
QgsProject.instance().addMapLayer(loaded_layer)
|
||||
self._apply_atlas_style(loaded_layer)
|
||||
print("[TabBLogic] Atlasobjekte aus Verfahrens-DB geladen und gestylt")
|
||||
return loaded_layer
|
||||
|
||||
def set_kartenname_for_auswahl(self, auswahl: str) -> None:
|
||||
"""Setzt die Projektvariable ``sn_kartenname`` anhand der Kartennamen-Auswahl."""
|
||||
kartenname = KARTENNAME_BY_AUSWAHL.get(auswahl, "")
|
||||
@@ -178,9 +324,20 @@ class TabBLogic:
|
||||
else:
|
||||
ziel_w, ziel_h = float(din_dims[0]), float(din_dims[1])
|
||||
|
||||
if ziel_w < DIN_GROESSEN["DIN A4"][0] or ziel_h < DIN_GROESSEN["DIN A4"][1]:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Blattgröße zu klein",
|
||||
"Die Zielgröße darf nicht kleiner als DIN A4 sein.",
|
||||
)
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
|
||||
# ─── 7. Passt auf ein Blatt? -> Layout erzeugen ───────────────────
|
||||
print(f"[TabBLogic] plotgroesse=({plotgroesse_w:.1f}x{plotgroesse_h:.1f}), "
|
||||
f"zielgroesse=({ziel_w:.1f}x{ziel_h:.1f}), passt={plotgroesse_w <= ziel_w and plotgroesse_h <= ziel_h}")
|
||||
if plotgroesse_w > ziel_w or plotgroesse_h > ziel_h:
|
||||
if plotgroesse_w <= ziel_h and plotgroesse_h <= ziel_w:
|
||||
ziel_w, ziel_h = ziel_h, ziel_w
|
||||
|
||||
if plotgroesse_w <= ziel_w and plotgroesse_h <= ziel_h:
|
||||
kartenname = get_variable(KARTENNAME_VAR, scope="project") or KARTENNAME_BY_AUSWAHL.get(
|
||||
kartenname_auswahl, "Vorlage"
|
||||
@@ -247,7 +404,154 @@ class TabBLogic:
|
||||
"Ausdruck als Atlas anlegen?",
|
||||
default=True,
|
||||
)
|
||||
print(f"[TabBLogic] Atlas-Rückfrage: ja={ja}, geplante_seiten={anzahl_seiten}")
|
||||
if not ja:
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": anzahl_seiten}
|
||||
|
||||
atlas_layer = self._create_atlasobjekte_layer(
|
||||
layer=layer,
|
||||
extent=extent,
|
||||
pages_x=pages_x,
|
||||
pages_y=pages_y,
|
||||
seite_karte_w=seite_karte_w,
|
||||
seite_karte_h=seite_karte_h,
|
||||
massstab_zahl=massstab_zahl,
|
||||
)
|
||||
if atlas_layer is None:
|
||||
self.pruefmanager.zeige_hinweis(
|
||||
"Atlasobjekte",
|
||||
"Atlasobjekte-Layer konnte nicht erzeugt werden.",
|
||||
)
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
print("[TabBLogic] Atlasobjekte-Layer erfolgreich erzeugt")
|
||||
|
||||
try:
|
||||
anzahl_seiten = int(atlas_layer.featureCount())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Berechne die Kachelgröße aus den Atlasobjekten.
|
||||
# Für die Layout-Kartengröße muss die größte Atlas-Kachel passen,
|
||||
# sonst werden größere Atlasobjekte abgeschnitten.
|
||||
total_w_m = 0.0
|
||||
total_h_m = 0.0
|
||||
min_w_m = math.inf
|
||||
min_h_m = math.inf
|
||||
max_w_m = 0.0
|
||||
max_h_m = 0.0
|
||||
feature_count = 0
|
||||
get_features = getattr(atlas_layer, "getFeatures", None)
|
||||
if callable(get_features):
|
||||
try:
|
||||
for feat in get_features():
|
||||
geom = feat.geometry() if hasattr(feat, "geometry") else None
|
||||
if geom is None or geom.isEmpty():
|
||||
continue
|
||||
bbox = geom.boundingBox() if hasattr(geom, "boundingBox") else None
|
||||
if bbox is None:
|
||||
continue
|
||||
feat_w_m = float(bbox.width())
|
||||
feat_h_m = float(bbox.height())
|
||||
total_w_m += feat_w_m
|
||||
total_h_m += feat_h_m
|
||||
min_w_m = min(min_w_m, feat_w_m)
|
||||
min_h_m = min(min_h_m, feat_h_m)
|
||||
max_w_m = max(max_w_m, feat_w_m)
|
||||
max_h_m = max(max_h_m, feat_h_m)
|
||||
feature_count += 1
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if feature_count > 0:
|
||||
avg_tile_w_m = total_w_m / feature_count
|
||||
avg_tile_h_m = total_h_m / feature_count
|
||||
if not math.isfinite(min_w_m):
|
||||
min_w_m = avg_tile_w_m
|
||||
if not math.isfinite(min_h_m):
|
||||
min_h_m = avg_tile_h_m
|
||||
target_tile_w_m = max_w_m
|
||||
target_tile_h_m = max_h_m
|
||||
else:
|
||||
avg_tile_w_m = seite_karte_w * massstab_zahl / 1000.0
|
||||
avg_tile_h_m = seite_karte_h * massstab_zahl / 1000.0
|
||||
min_w_m = avg_tile_w_m
|
||||
min_h_m = avg_tile_h_m
|
||||
max_w_m = avg_tile_w_m
|
||||
max_h_m = avg_tile_h_m
|
||||
target_tile_w_m = avg_tile_w_m
|
||||
target_tile_h_m = avg_tile_h_m
|
||||
|
||||
# Konvertiere Kachelgrößen zu mm
|
||||
avg_tile_w_mm = avg_tile_w_m * 1000.0 / massstab_zahl
|
||||
avg_tile_h_mm = avg_tile_h_m * 1000.0 / massstab_zahl
|
||||
min_tile_w_mm = min_w_m * 1000.0 / massstab_zahl
|
||||
min_tile_h_mm = min_h_m * 1000.0 / massstab_zahl
|
||||
max_tile_w_mm = max_w_m * 1000.0 / massstab_zahl
|
||||
max_tile_h_mm = max_h_m * 1000.0 / massstab_zahl
|
||||
target_tile_w_mm = target_tile_w_m * 1000.0 / massstab_zahl
|
||||
target_tile_h_mm = target_tile_h_m * 1000.0 / massstab_zahl
|
||||
|
||||
# Layout-Kartengröße = größte Kachelgröße
|
||||
atlas_map_w = max(1.0, target_tile_w_mm)
|
||||
atlas_map_h = max(1.0, target_tile_h_mm)
|
||||
atlas_page_w = atlas_map_w + 210.0
|
||||
atlas_page_h = atlas_map_h + 20.0
|
||||
|
||||
# Debug: Atlasobjekte Geometrien
|
||||
print(
|
||||
f"[TabBLogic] Atlasobjekte Geometrien (Meter): "
|
||||
f"total_w={total_w_m:.1f}m, total_h={total_h_m:.1f}m, "
|
||||
f"min_w={min_w_m:.1f}m, min_h={min_h_m:.1f}m, "
|
||||
f"avg_w={avg_tile_w_m:.1f}m, avg_h={avg_tile_h_m:.1f}m, "
|
||||
f"max_w={max_w_m:.1f}m, max_h={max_h_m:.1f}m, features={feature_count}"
|
||||
)
|
||||
print(
|
||||
f"[TabBLogic] Atlas layout Größen: "
|
||||
f"page=(x=10, y=10, w={atlas_page_w:.1f}mm, h={atlas_page_h:.1f}mm), "
|
||||
f"map=(x=10, y=10, w={atlas_map_w:.1f}mm, h={atlas_map_h:.1f}mm), "
|
||||
f"kachel_min_mm=({min_tile_w_mm:.1f}x{min_tile_h_mm:.1f}), "
|
||||
f"kachel_avg_mm=({avg_tile_w_mm:.1f}x{avg_tile_h_mm:.1f}), "
|
||||
f"kachel_max_mm=({max_tile_w_mm:.1f}x{max_tile_h_mm:.1f})"
|
||||
)
|
||||
|
||||
kartenname = get_variable(KARTENNAME_VAR, scope="project") or KARTENNAME_BY_AUSWAHL.get(
|
||||
kartenname_auswahl, "Atlas"
|
||||
)
|
||||
thema = get_variable(VIEW_VAR, scope="project") or ""
|
||||
vorlage_name, bestaetigt = self.pruefmanager.frage_text(
|
||||
"Neue Atlasvorlage anlegen",
|
||||
"Bezeichnung der Vorlage:",
|
||||
default_text=f"{kartenname} Atlas",
|
||||
)
|
||||
print(f"[TabBLogic] Atlas frage_text Ergebnis: name='{vorlage_name}', bestaetigt={bestaetigt}")
|
||||
if not bestaetigt:
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": anzahl_seiten}
|
||||
|
||||
vorlage_name = (vorlage_name or "").strip() or f"{kartenname} Atlas"
|
||||
|
||||
try:
|
||||
print(
|
||||
f"[TabBLogic] Rufe create_atlas_layout auf: name='{vorlage_name}', "
|
||||
f"page=({atlas_page_w:.1f}x{atlas_page_h:.1f}), "
|
||||
f"map=({atlas_map_w:.1f}x{atlas_map_h:.1f}), massstab={massstab_zahl}, thema='{thema}'"
|
||||
)
|
||||
Layout().create_atlas_layout(
|
||||
name=vorlage_name,
|
||||
page_width_mm=atlas_page_w,
|
||||
page_height_mm=atlas_page_h,
|
||||
map_width_mm=atlas_map_w,
|
||||
map_height_mm=atlas_map_h,
|
||||
extent=extent,
|
||||
plotmassstab=massstab_zahl,
|
||||
atlas_layer=atlas_layer,
|
||||
thema=thema,
|
||||
)
|
||||
print("[TabBLogic] create_atlas_layout erfolgreich abgeschlossen")
|
||||
except ValueError as exc:
|
||||
self.pruefmanager.zeige_hinweis("Atlasvorlage anlegen", str(exc))
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
except Exception as exc:
|
||||
self.pruefmanager.zeige_hinweis("Atlasvorlage anlegen", f"Die Atlasvorlage konnte nicht angelegt werden: {exc}")
|
||||
return {"ok": False, "switch_to_tab_a": False, "atlas_seiten": 0}
|
||||
|
||||
return {"ok": True, "switch_to_tab_a": False, "atlas_seiten": anzahl_seiten}
|
||||
Reference in New Issue
Block a user