2025-12-19 14:29:52 +01:00
|
|
|
|
"""
|
|
|
|
|
|
sn_basis/functions/qgiscore_wrapper.py – zentrale QGIS-Core-Abstraktion
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from typing import Type, Any
|
|
|
|
|
|
|
|
|
|
|
|
from sn_basis.functions.qt_wrapper import (
|
|
|
|
|
|
QUrl,
|
|
|
|
|
|
QEventLoop,
|
|
|
|
|
|
QNetworkRequest,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
|
# QGIS-Symbole (werden dynamisch gesetzt)
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
QgsProject: Type[Any]
|
|
|
|
|
|
QgsVectorLayer: Type[Any]
|
|
|
|
|
|
QgsNetworkAccessManager: Type[Any]
|
|
|
|
|
|
Qgis: Type[Any]
|
2026-01-08 17:13:51 +01:00
|
|
|
|
QgsMapLayerProxyModel: Type[Any]
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QGIS_AVAILABLE = False
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
|
# Versuch: QGIS-Core importieren
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
from qgis.core import (
|
|
|
|
|
|
QgsProject as _QgsProject,
|
|
|
|
|
|
QgsVectorLayer as _QgsVectorLayer,
|
|
|
|
|
|
QgsNetworkAccessManager as _QgsNetworkAccessManager,
|
|
|
|
|
|
Qgis as _Qgis,
|
2026-01-08 17:13:51 +01:00
|
|
|
|
QgsMapLayerProxyModel as _QgsMaplLayerProxyModel
|
2025-12-19 14:29:52 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
QgsProject = _QgsProject
|
|
|
|
|
|
QgsVectorLayer = _QgsVectorLayer
|
|
|
|
|
|
QgsNetworkAccessManager = _QgsNetworkAccessManager
|
|
|
|
|
|
Qgis = _Qgis
|
2026-01-08 17:13:51 +01:00
|
|
|
|
QgsMapLayerProxyModel=_QgsMaplLayerProxyModel
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
QGIS_AVAILABLE = True
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
|
# Mock-Modus
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
QGIS_AVAILABLE = False
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQgsProject:
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
|
self._variables = {}
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
|
def instance() -> "_MockQgsProject":
|
|
|
|
|
|
return _MockQgsProject()
|
|
|
|
|
|
|
|
|
|
|
|
def read(self) -> bool:
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
QgsProject = _MockQgsProject
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQgsVectorLayer:
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
self._valid = True
|
|
|
|
|
|
|
|
|
|
|
|
def isValid(self) -> bool:
|
|
|
|
|
|
return self._valid
|
|
|
|
|
|
|
|
|
|
|
|
def loadNamedStyle(self, path: str):
|
|
|
|
|
|
return True, ""
|
|
|
|
|
|
|
|
|
|
|
|
def triggerRepaint(self) -> None:
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
QgsVectorLayer = _MockQgsVectorLayer
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQgsNetworkAccessManager:
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
|
def instance():
|
|
|
|
|
|
return _MockQgsNetworkAccessManager()
|
|
|
|
|
|
|
|
|
|
|
|
def head(self, request: Any):
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
QgsNetworkAccessManager = _MockQgsNetworkAccessManager
|
|
|
|
|
|
|
|
|
|
|
|
class _MockQgis:
|
|
|
|
|
|
class MessageLevel:
|
|
|
|
|
|
Success = 0
|
|
|
|
|
|
Info = 1
|
|
|
|
|
|
Warning = 2
|
|
|
|
|
|
Critical = 3
|
|
|
|
|
|
|
|
|
|
|
|
Qgis = _MockQgis
|
|
|
|
|
|
|
2026-01-08 17:13:51 +01:00
|
|
|
|
class _MockQgsMapLayerProxyModel:
|
|
|
|
|
|
# Layer-Typen (entsprechen QGIS-Konstanten)
|
|
|
|
|
|
NoLayer = 0
|
|
|
|
|
|
VectorLayer = 1
|
|
|
|
|
|
RasterLayer = 2
|
|
|
|
|
|
PluginLayer = 3
|
|
|
|
|
|
MeshLayer = 4
|
|
|
|
|
|
VectorTileLayer = 5
|
|
|
|
|
|
PointCloudLayer = 6
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
QgsMapLayerProxyModel = _MockQgsMapLayerProxyModel
|
2025-12-19 14:29:52 +01:00
|
|
|
|
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
|
# Netzwerk
|
|
|
|
|
|
# ---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
class NetworkReply:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Minimaler Wrapper für Netzwerkantworten.
|
|
|
|
|
|
"""
|
|
|
|
|
|
def __init__(self, error: int):
|
|
|
|
|
|
self.error = error
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def network_head(url: str) -> NetworkReply | None:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Führt einen HTTP-HEAD-Request aus.
|
|
|
|
|
|
|
|
|
|
|
|
Rückgabe:
|
|
|
|
|
|
- NetworkReply(error=0) → erreichbar
|
|
|
|
|
|
- NetworkReply(error!=0) → nicht erreichbar
|
|
|
|
|
|
- None → Netzwerk nicht verfügbar / Fehler beim Request
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
if not QGIS_AVAILABLE:
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
if QUrl is None or QNetworkRequest is None:
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
manager = QgsNetworkAccessManager.instance()
|
|
|
|
|
|
request = QNetworkRequest(QUrl(url))
|
|
|
|
|
|
reply = manager.head(request)
|
|
|
|
|
|
|
|
|
|
|
|
# synchron warten (kurz)
|
|
|
|
|
|
if QEventLoop is not None:
|
|
|
|
|
|
loop = QEventLoop()
|
|
|
|
|
|
reply.finished.connect(loop.quit)
|
|
|
|
|
|
loop.exec()
|
|
|
|
|
|
|
|
|
|
|
|
return NetworkReply(error=reply.error())
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
return None
|