Feature/vkz differenzierung #20
@@ -9,10 +9,23 @@ from sn_basis.functions import (
|
||||
from sn_basis.functions import QMessageBox
|
||||
from sn_basis.functions.qt_wrapper import QVariant
|
||||
from sn_basis.functions.variable_wrapper import get_variable
|
||||
from sn_basis.functions.dialog_wrapper import ask_bror_kombination
|
||||
|
||||
alkis_sf_url = "https://geodienste.sachsen.de/aaa/public_alkis/sf/wfs"
|
||||
typename = "adv:AX_BauRaumOderBodenordnungsrecht"
|
||||
|
||||
#: Attribute, die aus dem BROR-WFS-Dienst geladen und im Memory-Layer gespeichert werden.
|
||||
BROR_ATTRIBUTE_FELDER = [
|
||||
"artderfestlegung",
|
||||
"ausfuehrendestelle_ax_dienststelle_schluessel_stelle",
|
||||
"adv_name",
|
||||
"bezeichnung",
|
||||
"datumanordnung",
|
||||
"datumbesitzeinweisung",
|
||||
"datumrechtskraft",
|
||||
"datumabgabe",
|
||||
]
|
||||
|
||||
class LoadStatus(Enum):
|
||||
"""Status eines Layer-Ladevorgangs.
|
||||
|
||||
@@ -83,11 +96,13 @@ def verfahrensgebiet_alkis(tab_widget):
|
||||
if status == LoadStatus.KEEP:
|
||||
return existing, status, []
|
||||
|
||||
# WFS mit Filter laden
|
||||
# WFS mit Filter laden – nur erste 5 Stellen der VKZ für den Vergleich verwenden,
|
||||
# da die Daten im Dienst ggf. abweichende Suffixe führen.
|
||||
vkz_prefix = verfahrensnummer[:5]
|
||||
wfs_uri_find = (
|
||||
f"url='{alkis_sf_url}' typename='{typename}' srsname='EPSG:25833' "
|
||||
f"sql=SELECT * FROM AX_BauRaumOderBodenordnungsrecht "
|
||||
f"WHERE bezeichnung LIKE '{verfahrensnummer}%'"
|
||||
f"WHERE bezeichnung LIKE '{vkz_prefix}%'"
|
||||
)
|
||||
temp_layer = QgsVectorLayer(wfs_uri_find, "TempVerfahrensgebiet", "WFS")
|
||||
|
||||
@@ -101,7 +116,32 @@ def verfahrensgebiet_alkis(tab_widget):
|
||||
f"Verfahrenskennzeichen {verfahrensnummer} nicht im WFS gefunden.")
|
||||
return None, LoadStatus.NONE, []
|
||||
|
||||
union_geom = QgsGeometry.unaryUnion([f.geometry() for f in features])
|
||||
# Objekte nach (adv_name, bezeichnung) gruppieren
|
||||
kombinationen: dict[tuple[str, str], list] = {}
|
||||
for feat in features:
|
||||
try:
|
||||
adv_name_val = str(feat.attribute("adv_name") or "")
|
||||
bezeichnung_val = str(feat.attribute("bezeichnung") or "")
|
||||
except Exception:
|
||||
adv_name_val = ""
|
||||
bezeichnung_val = ""
|
||||
key = (adv_name_val, bezeichnung_val)
|
||||
if key not in kombinationen:
|
||||
kombinationen[key] = []
|
||||
kombinationen[key].append(feat)
|
||||
|
||||
if len(kombinationen) == 1:
|
||||
selected_key = next(iter(kombinationen))
|
||||
selected_feats = kombinationen[selected_key]
|
||||
else:
|
||||
# Mehrere Kombinationen → Nutzerauswahl
|
||||
key_list = sorted(kombinationen.keys())
|
||||
selected_key = ask_bror_kombination(tab_widget, key_list)
|
||||
if selected_key is None:
|
||||
return None, LoadStatus.NONE, []
|
||||
selected_feats = kombinationen[selected_key]
|
||||
|
||||
union_geom = QgsGeometry.unaryUnion([f.geometry() for f in selected_feats])
|
||||
if union_geom is None or union_geom.isEmpty():
|
||||
QMessageBox.critical(tab_widget, "Fehler", "Keine Geometrien zum Verschmelzen gefunden.")
|
||||
return None, LoadStatus.NONE, []
|
||||
@@ -110,14 +150,30 @@ def verfahrensgebiet_alkis(tab_widget):
|
||||
crs = temp_layer.crs().authid()
|
||||
memory_layer = QgsVectorLayer(f"Polygon?crs={crs}", "Verfahrensgebiet", "memory")
|
||||
pr = memory_layer.dataProvider()
|
||||
pr.addAttributes([QgsField("VKZ", QVariant.String)])
|
||||
pr.addAttributes([QgsField(attr, QVariant.String) for attr in BROR_ATTRIBUTE_FELDER])
|
||||
memory_layer.updateFields()
|
||||
|
||||
# Attributwerte aus dem ersten Feature der gewählten Kombination übernehmen
|
||||
first_feat = selected_feats[0]
|
||||
attrs = []
|
||||
for attr in BROR_ATTRIBUTE_FELDER:
|
||||
try:
|
||||
val = first_feat.attribute(attr)
|
||||
if val is None:
|
||||
attrs.append("")
|
||||
elif type(val).__name__ == "QDate":
|
||||
# QDate-Objekte als DD.MM.YYYY formatieren
|
||||
attrs.append(val.toString("dd.MM.yyyy"))
|
||||
else:
|
||||
attrs.append(str(val))
|
||||
except Exception:
|
||||
attrs.append("")
|
||||
|
||||
feat_union = QgsFeature()
|
||||
feat_union.setGeometry(union_geom)
|
||||
feat_union.setAttributes([verfahrensnummer])
|
||||
feat_union.setAttributes(attrs)
|
||||
pr.addFeatures([feat_union])
|
||||
memory_layer.updateExtents()
|
||||
|
||||
# Status: FIRST oder RELOAD; features für Gemarkungsermittlung weitergeben
|
||||
return memory_layer, status, features
|
||||
# Status: FIRST oder RELOAD; selected_feats für Gemarkungsermittlung weitergeben
|
||||
return memory_layer, status, selected_feats
|
||||
|
||||
@@ -26,7 +26,7 @@ optionaler Umringsprüfung:
|
||||
- Abschlussmeldung mit Zählung.
|
||||
|
||||
Das BROR-Objekt (``AX_BauRaumOderBodenordnungsrecht``) bleibt bei Erfolg als
|
||||
temporärer Layer ``BauRaumOrdnungsrecht (ALKIS)`` im Projekt erhalten.
|
||||
temporärer Layer ``BauRaumOderBodenordnungsrecht (ALKIS)`` im Projekt erhalten.
|
||||
|
||||
**Rückgabe:**
|
||||
``Tuple[enriched_layer, flst_layer, bror_layer, LoadStatus]``
|
||||
@@ -71,9 +71,12 @@ from sn_verfahrensgebiet.functions.knickpunkt_pruefung import (
|
||||
# Feldname für das Verfahrenskennzeichen im enriched Layer
|
||||
FELD_VKZ = "verfahrensnummer"
|
||||
#: Anzeigename des BROR-Layers im Projekt
|
||||
BROR_LAYER_NAME = "BauRaumOrdnungsrecht (ALKIS)"
|
||||
BROR_LAYER_NAME = "BauRaumOderBodenordnungsrecht (ALKIS)"
|
||||
#: Projektvariable für die Flächentoleranz (in m²); Default 0
|
||||
FLAECHEN_TOLERANZ_VARIABLE = "flaechen_toleranz_m2"
|
||||
#: Minimale implizite Flächentoleranz – Abweichungen unter diesem Wert
|
||||
#: lösen keine Konfliktabfrage aus (Gleitkomma-Ungenauigkeiten vermeiden).
|
||||
MINDEST_FLAECHEN_TOLERANZ_M2 = 0.01
|
||||
|
||||
|
||||
|
||||
@@ -223,7 +226,7 @@ def _vergleiche_flaechen(
|
||||
Parameters
|
||||
----------
|
||||
bror_layer :
|
||||
BauRaumOrdnungsrecht-Layer.
|
||||
BauRaumOderBodenordnungsrecht-Layer.
|
||||
vg_layer :
|
||||
Enriched Verfahrensgebiet-Layer.
|
||||
toleranz_m2 :
|
||||
@@ -236,7 +239,8 @@ def _vergleiche_flaechen(
|
||||
"""
|
||||
bror_flaeche = _flaeche_des_layers(bror_layer)
|
||||
vg_flaeche = _flaeche_des_layers(vg_layer)
|
||||
stimmt_ueberein = abs(bror_flaeche - vg_flaeche) <= toleranz_m2
|
||||
diff = abs(bror_flaeche - vg_flaeche)
|
||||
stimmt_ueberein = diff < MINDEST_FLAECHEN_TOLERANZ_M2 or diff <= toleranz_m2
|
||||
return bror_flaeche, vg_flaeche, stimmt_ueberein
|
||||
|
||||
|
||||
@@ -260,7 +264,7 @@ def verfahrensgebiet_alkis_komplett(
|
||||
6. ``_vergleiche_flaechen(...)`` – Flächenvergleich als Gate.
|
||||
7. Ggf. ``umringspruefung(...)`` nach Nutzerbestätigung.
|
||||
|
||||
Der BROR-Layer (``BauRaumOrdnungsrecht (ALKIS)``) bleibt bei Erfolg
|
||||
Der BROR-Layer (``BauRaumOderBodenordnungsrecht (ALKIS)``) bleibt bei Erfolg
|
||||
im Projekt. Bei Abbruch/Fehler wird er entfernt, falls er in diesem
|
||||
Lauf hinzugefügt wurde.
|
||||
|
||||
@@ -274,7 +278,7 @@ def verfahrensgebiet_alkis_komplett(
|
||||
Tuple[Optional[enriched_layer], Optional[flst_layer], Optional[bror_layer], LoadStatus]
|
||||
- ``enriched_layer``: Memory-Layer „Verfahrensgebiet".
|
||||
- ``flst_layer``: Flurstücke-Layer (bleibt im Projekt).
|
||||
- ``bror_layer``: BROR-Layer ``BauRaumOrdnungsrecht (ALKIS)``
|
||||
- ``bror_layer``: BROR-Layer ``BauRaumOderBodenordnungsrecht (ALKIS)``
|
||||
(bleibt bei Erfolg im Projekt).
|
||||
- :class:`LoadStatus`: ``FIRST``, ``RELOAD`` oder ``NONE``.
|
||||
"""
|
||||
@@ -298,6 +302,7 @@ def verfahrensgebiet_alkis_komplett(
|
||||
return None, None, None, LoadStatus.NONE
|
||||
|
||||
alkis_vg_layer, vg_status, _ = verfahrensgebiet_alkis(tab_widget)
|
||||
progress.raise_to_front()
|
||||
|
||||
if vg_status == LoadStatus.NONE or not alkis_vg_layer:
|
||||
return None, None, None, LoadStatus.NONE
|
||||
@@ -433,9 +438,9 @@ def verfahrensgebiet_alkis_komplett(
|
||||
entscheidung = ask_detailpruefung_oder_vg_laden(
|
||||
tab_widget,
|
||||
"Abweichung erkannt",
|
||||
f"Abweichung zwischen BauRaumOrdnungsrecht-Objekt und abgeleitetem "
|
||||
f"Abweichung zwischen BauRaumOderBodenordnungsrecht-Objekt und abgeleitetem "
|
||||
f"Verfahrensgebiet erkannt.\n\n"
|
||||
f"BauRaumOrdnungsrecht: {bror_flaeche:.2f} m²\n"
|
||||
f"BauRaumOderBodenordnungsrecht: {bror_flaeche:.2f} m²\n"
|
||||
f"Verfahrensgebiet: {vg_flaeche:.2f} m²\n"
|
||||
f"Differenz: {diff:.2f} m²\n\n"
|
||||
f"Wie möchten Sie fortfahren?",
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||
<qgis layerType="Vector" styleCategories="Symbology" version="4.0.1-Norrköping">
|
||||
<renderer-v2 enableorderby="0" forceraster="0" referencescale="-1" symbollevels="0" type="singleSymbol">
|
||||
<symbols>
|
||||
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="0" type="fill">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer class="SimpleFill" enabled="1" id="{c32b7d26-d63f-4a20-b079-a5caa68d53db}" locked="0" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="214,165,49,40,hsv:0.11719444394111633,0.77273213863372803,0.83793395757675171,0.15686275064945221"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="206,185,47,255,hsv:0.14452777802944183,0.77273213863372803,0.80689710378646851,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.8"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</symbols>
|
||||
<rotation/>
|
||||
<sizescale/>
|
||||
<data-defined-properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data-defined-properties>
|
||||
</renderer-v2>
|
||||
<selection mode="Default">
|
||||
<selectionColor invalid="1"/>
|
||||
<selectionSymbol>
|
||||
<symbol alpha="1" clip_to_extent="1" force_rhr="0" frame_rate="10" is_animated="0" name="" type="fill">
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
<layer class="SimpleFill" enabled="1" id="{9cbdf1f0-8055-4075-828c-a33555f4068e}" locked="0" pass="0">
|
||||
<Option type="Map">
|
||||
<Option name="border_width_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="color" type="QString" value="0,0,255,255,rgb:0,0,1,1"/>
|
||||
<Option name="joinstyle" type="QString" value="bevel"/>
|
||||
<Option name="offset" type="QString" value="0,0"/>
|
||||
<Option name="offset_map_unit_scale" type="QString" value="3x:0,0,0,0,0,0"/>
|
||||
<Option name="offset_unit" type="QString" value="MM"/>
|
||||
<Option name="outline_color" type="QString" value="35,35,35,255,rgb:0.1372549,0.1372549,0.1372549,1"/>
|
||||
<Option name="outline_style" type="QString" value="solid"/>
|
||||
<Option name="outline_width" type="QString" value="0.26"/>
|
||||
<Option name="outline_width_unit" type="QString" value="MM"/>
|
||||
<Option name="style" type="QString" value="solid"/>
|
||||
</Option>
|
||||
<data_defined_properties>
|
||||
<Option type="Map">
|
||||
<Option name="name" type="QString" value=""/>
|
||||
<Option name="properties"/>
|
||||
<Option name="type" type="QString" value="collection"/>
|
||||
</Option>
|
||||
</data_defined_properties>
|
||||
</layer>
|
||||
</symbol>
|
||||
</selectionSymbol>
|
||||
</selection>
|
||||
<blendMode>0</blendMode>
|
||||
<featureBlendMode>0</featureBlendMode>
|
||||
<layerGeometryType>2</layerGeometryType>
|
||||
</qgis>
|
||||
@@ -61,12 +61,16 @@ class _DummyGeom:
|
||||
|
||||
|
||||
class _DummyFeature:
|
||||
def __init__(self, geom=None):
|
||||
def __init__(self, geom=None, attrs=None):
|
||||
self._geom = geom or _DummyGeom()
|
||||
self._attrs = attrs or {}
|
||||
|
||||
def geometry(self):
|
||||
return self._geom
|
||||
|
||||
def attribute(self, name):
|
||||
return self._attrs.get(name)
|
||||
|
||||
|
||||
class _DummyTempLayer:
|
||||
def __init__(self, valid=True, features=None):
|
||||
@@ -139,7 +143,7 @@ class TestVerfahrensgebietAlkis(unittest.TestCase):
|
||||
def test_verfahrensgebiet_alkis_fails_when_verfahrensnummer_missing(self, _mock_get_var):
|
||||
_DummyMessageBox.last_critical = None
|
||||
|
||||
layer, status = vg.verfahrensgebiet_alkis(tab_widget=None)
|
||||
layer, status, feats = vg.verfahrensgebiet_alkis(tab_widget=None)
|
||||
|
||||
self.assertIsNone(layer)
|
||||
self.assertEqual(status, vg.LoadStatus.NONE)
|
||||
@@ -153,7 +157,7 @@ class TestVerfahrensgebietAlkis(unittest.TestCase):
|
||||
_DummyMessageBox.last_critical = None
|
||||
mock_qgsvectorlayer.return_value = _DummyTempLayer(valid=False)
|
||||
|
||||
layer, status = vg.verfahrensgebiet_alkis(tab_widget=None)
|
||||
layer, status, feats = vg.verfahrensgebiet_alkis(tab_widget=None)
|
||||
|
||||
self.assertIsNone(layer)
|
||||
self.assertEqual(status, vg.LoadStatus.NONE)
|
||||
@@ -165,8 +169,10 @@ class TestVerfahrensgebietAlkis(unittest.TestCase):
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.get_variable", return_value="VKZ123")
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsVectorLayer")
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QMessageBox", new=_DummyMessageBox)
|
||||
def test_verfahrensgebiet_alkis_success_returns_memory_layer(self, mock_qgsvectorlayer, _mock_get_var, _mock_check, _mock_union, mock_feature_cls):
|
||||
temp_layer = _DummyTempLayer(valid=True, features=[_DummyFeature()])
|
||||
def test_verfahrensgebiet_alkis_success_single_kombination(self, mock_qgsvectorlayer, _mock_get_var, _mock_check, _mock_union, mock_feature_cls):
|
||||
"""Einzelne (adv_name, bezeichnung)-Kombination → kein Dialog, Memory-Layer zurück."""
|
||||
feat = _DummyFeature(attrs={"adv_name": "Bodensanierung", "bezeichnung": "VKZ12/001"})
|
||||
temp_layer = _DummyTempLayer(valid=True, features=[feat])
|
||||
memory_layer = _DummyMemoryLayer()
|
||||
mock_qgsvectorlayer.side_effect = [temp_layer, memory_layer]
|
||||
|
||||
@@ -174,10 +180,63 @@ class TestVerfahrensgebietAlkis(unittest.TestCase):
|
||||
mock_feature.setGeometry.return_value = None
|
||||
mock_feature.setAttributes.return_value = None
|
||||
|
||||
layer, status = vg.verfahrensgebiet_alkis(tab_widget=None)
|
||||
layer, status, feats = vg.verfahrensgebiet_alkis(tab_widget=None)
|
||||
|
||||
self.assertIs(layer, memory_layer)
|
||||
self.assertEqual(status, vg.LoadStatus.FIRST)
|
||||
self.assertEqual(len(feats), 1)
|
||||
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.ask_bror_kombination")
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsFeature")
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsGeometry.unaryUnion", return_value=_DummyGeom(empty=False))
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis._check_existing_layer", return_value=(None, vg.LoadStatus.FIRST))
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.get_variable", return_value="VKZ123")
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsVectorLayer")
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QMessageBox", new=_DummyMessageBox)
|
||||
def test_verfahrensgebiet_alkis_multi_kombination_dialog_auswahl(
|
||||
self, mock_qgsvectorlayer, _mock_get_var, _mock_check, _mock_union, mock_feature_cls, mock_dialog
|
||||
):
|
||||
"""Zwei verschiedene Kombinationen → Dialog wird gezeigt, gewählte Features genutzt."""
|
||||
feat1 = _DummyFeature(attrs={"adv_name": "ADV-A", "bezeichnung": "VKZ12/001"})
|
||||
feat2 = _DummyFeature(attrs={"adv_name": "ADV-B", "bezeichnung": "VKZ12/002"})
|
||||
temp_layer = _DummyTempLayer(valid=True, features=[feat1, feat2])
|
||||
memory_layer = _DummyMemoryLayer()
|
||||
mock_qgsvectorlayer.side_effect = [temp_layer, memory_layer]
|
||||
mock_dialog.return_value = ("ADV-A", "VKZ12/001")
|
||||
|
||||
mock_feature = mock_feature_cls.return_value
|
||||
mock_feature.setGeometry.return_value = None
|
||||
mock_feature.setAttributes.return_value = None
|
||||
|
||||
layer, status, feats = vg.verfahrensgebiet_alkis(tab_widget=None)
|
||||
|
||||
mock_dialog.assert_called_once()
|
||||
self.assertIs(layer, memory_layer)
|
||||
self.assertEqual(status, vg.LoadStatus.FIRST)
|
||||
# Nur feat1 gehört zur gewählten Kombination
|
||||
self.assertEqual(feats, [feat1])
|
||||
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.ask_bror_kombination")
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis._check_existing_layer", return_value=(None, vg.LoadStatus.FIRST))
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.get_variable", return_value="VKZ123")
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QgsVectorLayer")
|
||||
@patch("sn_verfahrensgebiet.functions.verfahrensgebiet_alkis.QMessageBox", new=_DummyMessageBox)
|
||||
def test_verfahrensgebiet_alkis_multi_kombination_dialog_abbruch(
|
||||
self, mock_qgsvectorlayer, _mock_get_var, _mock_check, mock_dialog
|
||||
):
|
||||
"""Zwei verschiedene Kombinationen → Nutzer bricht Dialog ab → NONE."""
|
||||
feat1 = _DummyFeature(attrs={"adv_name": "ADV-A", "bezeichnung": "VKZ12/001"})
|
||||
feat2 = _DummyFeature(attrs={"adv_name": "ADV-B", "bezeichnung": "VKZ12/002"})
|
||||
temp_layer = _DummyTempLayer(valid=True, features=[feat1, feat2])
|
||||
mock_qgsvectorlayer.return_value = temp_layer
|
||||
mock_dialog.return_value = None # Nutzer bricht ab
|
||||
|
||||
layer, status, feats = vg.verfahrensgebiet_alkis(tab_widget=None)
|
||||
|
||||
mock_dialog.assert_called_once()
|
||||
self.assertIsNone(layer)
|
||||
self.assertEqual(status, vg.LoadStatus.NONE)
|
||||
self.assertEqual(feats, [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
+2
-29
@@ -169,9 +169,9 @@ class WorkingTab(QWidget):
|
||||
apply_style(flst_layer, "GIS_Flst_Beschriftung_ALKIS_NAS.qml")
|
||||
self.setze_haken(self.haken_flurst, True)
|
||||
|
||||
# BROR-Layer: einfache Darstellung setzen (roter Umring, transparent)
|
||||
# BROR-Layer: QML-Stil anwenden
|
||||
if bror_layer and bror_layer.isValid():
|
||||
_setze_bror_stil(bror_layer)
|
||||
apply_style(bror_layer, "BauRaumOderBodenordnungsrecht.qml")
|
||||
|
||||
# Enriched VG-Layer ins Projekt (ggf. bereits registriert, z.B. bei "als VG laden")
|
||||
if not project.mapLayer(enriched_layer.id()):
|
||||
@@ -547,31 +547,4 @@ class WorkingTab(QWidget):
|
||||
# Modul-Hilfsfunktionen
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _setze_bror_stil(layer) -> None:
|
||||
"""Setzt eine einfache Darstellung für den BauRaumOrdnungsrecht-Layer.
|
||||
|
||||
Roter Umring, halbtransparente Füllung; kein QGIS-Kontext → stilles Ignorieren.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
layer :
|
||||
BauRaumOrdnungsrecht-Memory-Layer (Polygon).
|
||||
"""
|
||||
try:
|
||||
from qgis.core import ( # type: ignore[import]
|
||||
QgsSimpleFillSymbolLayer,
|
||||
QgsFillSymbol,
|
||||
QgsSingleSymbolRenderer,
|
||||
)
|
||||
from qgis.PyQt.QtGui import QColor # type: ignore[import]
|
||||
from qgis.PyQt.QtCore import Qt # type: ignore[import]
|
||||
|
||||
fill = QgsSimpleFillSymbolLayer()
|
||||
fill.setColor(QColor(220, 50, 50, 40)) # halbtransparent rot
|
||||
fill.setStrokeColor(QColor(220, 50, 50))
|
||||
fill.setStrokeWidth(0.8)
|
||||
symbol = QgsFillSymbol([fill])
|
||||
layer.setRenderer(QgsSingleSymbolRenderer(symbol))
|
||||
layer.triggerRepaint()
|
||||
except Exception:
|
||||
pass # Kein QGIS-Kontext (Tests, Mock-Modus) → Standarddarstellung
|
||||
|
||||
Reference in New Issue
Block a user