Druckbereich und Layoutkarte im KBS des Verfahrensgebiets (#99)

Bei anderem Projekt-KBS als dem des Verfahrensgebiets entstand das
Drucklayout mit leerer Karte und falschen Koordinaten: die Ausdehnung kam
im Layer-KBS, die Layoutkarte rechnete im Projekt-KBS. Die Hauptkarte
bekommt jetzt das KBS des Verfahrensgebiet-Layers, alle Druckbereiche
werden dorthin umgerechnet, ebenso das gezeichnete Druckrechteck.

Neue Wrapper-Funktionen transformiere_rechteck und zoom_auf_layer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 22:15:34 +02:00
co-authored by Claude Opus 5.5
parent 3e1431642b
commit f58d814313
7 changed files with 363 additions and 8 deletions
+46
View File
@@ -373,12 +373,21 @@ except Exception:
self.follow_visibility_preset_name = ""
self.keep_layer_set = False
self._grids = _MockQgsLayoutItemMapGridStack(self)
self._crs = None
self.crs_vor_extent = None # war das KBS gesetzt, als die Ausdehnung kam?
def setId(self, item_id: str) -> None:
self.item_id = item_id
def setCrs(self, crs: Any) -> None:
self._crs = crs
def crs(self) -> Any:
return self._crs
def setExtent(self, extent: Any) -> None:
self.extent = extent
self.crs_vor_extent = self._crs is not None
def setScale(self, scale: float) -> None:
self.scale = scale
@@ -1247,6 +1256,43 @@ def get_layer_extent(layer: Any) -> Any:
return None
def _crs_kennung(crs: Any) -> str:
authid = getattr(crs, "authid", None)
try:
return str(authid() or "") if callable(authid) else ""
except Exception:
return ""
def _crs_gueltig(crs: Any) -> bool:
if crs is None:
return False
is_valid = getattr(crs, "isValid", None)
try:
return bool(is_valid()) if callable(is_valid) else bool(_crs_kennung(crs))
except Exception:
return False
def transformiere_rechteck(rechteck: Any, quell_crs: Any, ziel_crs: Any, project: Any = None) -> Any:
"""Rechnet ein Rechteck (z. B. eine Layer-Ausdehnung) von ``quell_crs`` nach ``ziel_crs`` um (Basis #99).
Ausdehnungen von Layern stehen im KBS des Layers, Kartenansicht und Layoutkarte rechnen im
eigenen KBS. Unverändert zurück kommt das Rechteck, wenn es fehlt, eines der KBS fehlt oder
ungültig ist, beide gleich sind oder die Umrechnung scheitert.
"""
if rechteck is None or not _crs_gueltig(quell_crs) or not _crs_gueltig(ziel_crs):
return rechteck
quelle, ziel = _crs_kennung(quell_crs), _crs_kennung(ziel_crs)
if quelle and quelle == ziel:
return rechteck
try:
if project is None:
project = QgsProject.instance()
return QgsCoordinateTransform(quell_crs, ziel_crs, project).transformBoundingBox(rechteck)
except Exception:
return rechteck
# ---------------------------------------------------------
# Buffer-Layer erzeugen
# ---------------------------------------------------------
+22 -1
View File
@@ -8,7 +8,7 @@ from typing import Any, List, Type
from sn_basis.functions.qt_wrapper import QDockWidget
from sn_basis.functions.qgiscore_wrapper import QgsProject, QGIS_AVAILABLE
from sn_basis.functions.qgiscore_wrapper import QgsProject, QGIS_AVAILABLE, transformiere_rechteck
iface: Any
@@ -219,6 +219,27 @@ def remove_toolbar(toolbar: Any) -> None:
# Layer zum Projekt hinzufügen
# ---------------------------------------------------------
def zoom_auf_layer(layer: Any, canvas: Any = None) -> bool:
"""Zoomt die Kartenansicht auf den Layer; die Ausdehnung wird in das KBS der Kartenansicht umgerechnet.
``layer.extent()`` steht im KBS des Layers. Direkt an ``setExtent`` übergeben, landet der
Sprung an der falschen Stelle, sobald das Projekt-KBS ein anderes ist (Basis #99).
Gibt ``False`` zurück, wenn Layer oder Kartenansicht fehlen oder das Zoomen scheitert.
"""
if canvas is None:
map_canvas = getattr(iface, "mapCanvas", None)
canvas = map_canvas() if callable(map_canvas) else None
if layer is None or canvas is None:
return False
try:
ziel_crs = canvas.mapSettings().destinationCrs()
canvas.setExtent(transformiere_rechteck(layer.extent(), layer.crs(), ziel_crs))
canvas.refresh()
return True
except Exception:
return False
def get_active_layer() -> Any:
"""Im Layerbaum ausgewählter Layer oder ``None`` (Mock-Modus, kein Layer gewählt)."""
try: