attributwertverschiebung gefixt

This commit is contained in:
2026-05-01 23:53:20 +02:00
parent 00ee470e08
commit 8730e1bf96
+55 -16
View File
@@ -269,12 +269,14 @@ def _parse_alkis_gml_memory_layer(
if not feat_elems:
return None
# Felder aus erstem Feature ermitteln (geom_prop ausschließen)
# Felder aus ALLEN Features ermitteln (2-Pass), damit optionale Felder
# wie "istTeilVon" nicht verloren gehen, wenn sie im ersten Feature fehlen.
feld_namen: List[str] = ["gml_id"]
for child in feat_elems[0]:
local = child.tag.split("}")[-1] if "}" in child.tag else child.tag
if local not in feld_namen and local != geom_prop:
feld_namen.append(local)
for feat_el in feat_elems:
for child in feat_el:
local = child.tag.split("}")[-1] if "}" in child.tag else child.tag
if local not in feld_namen and local != geom_prop:
feld_namen.append(local)
# Memory-Layer anlegen
mem_uri = f"Point?crs=EPSG:25833" if geom_prop else "none"
@@ -1187,7 +1189,11 @@ def grenzpunkte_gemarkungsweise(
# ------------------------------------------------------------------
# Schritt 2b: PunktortTA pro Gemarkung + Batching
# ------------------------------------------------------------------
alle_pta_features: List = []
# Statt rohe QgsFeature-Objekte (positionsbasierte Attribute!) zu sammeln,
# speichern wir (geom, attrs-dict) – vollständig namensbasiert.
# Das verhindert Feldwert-Verschiebungen, wenn verschiedene Batches
# die Felder in unterschiedlicher Reihenfolge liefern.
alle_pta_records: List[Dict] = [] # {'geom': QgsGeometry, 'attrs': {name: val}}
gesehene_pta_ids: set[str] = set()
pta_feld_namen: List[str] = []
gehoert_zu_feld: Optional[str] = None
@@ -1250,21 +1256,27 @@ def grenzpunkte_gemarkungsweise(
cur_feld_namen = [f.name() for f in tmp.fields()]
if not pta_feld_namen:
pta_feld_namen = cur_feld_namen
# Globale Feldliste inkrementell um neue Felder erweitern
# (Union über alle Batches/Gemarkungen).
for n in cur_feld_namen:
if n not in pta_feld_namen:
pta_feld_namen.append(n)
# Referenzfeld beim ersten Batch erkennen, der es enthält
if gehoert_zu_feld is None:
gehoert_zu_feld = _erkenne_gehoert_zu_feld(tmp)
if gehoert_zu_feld:
info(
"Grenzpunkte",
f"Referenzfeld erkannt: '{gehoert_zu_feld}'. "
f"PunktortTA-Felder: {', '.join(pta_feld_namen)}",
f"PunktortTA-Felder bisher: {', '.join(pta_feld_namen)}",
duration=5,
)
else:
elif not pta_feld_namen:
warning(
"Grenzpunkte (Diagnose)",
"Kein Referenzfeld in AX_PunktortTA erkannt. "
"Vorhandene Felder: " + ", ".join(pta_feld_namen),
"Vorhandene Felder: " + ", ".join(cur_feld_namen),
duration=15,
)
@@ -1277,7 +1289,17 @@ def grenzpunkte_gemarkungsweise(
continue
if pta_id:
gesehene_pta_ids.add(pta_id)
alle_pta_features.append(feat)
# Attribute namensbasiert als Dict speichern – verhindert
# Positions-Verschiebung beim späteren Aufbau von punktort_layer.
_attrs: Dict[str, str] = {}
for n in cur_feld_namen:
if n:
try:
_attrs[n] = feat[n]
except Exception:
pass
alle_pta_records.append({'geom': feat.geometry(), 'attrs': _attrs})
neu += 1
if gehoert_zu_feld:
@@ -1303,7 +1325,7 @@ def grenzpunkte_gemarkungsweise(
)
# Abbruch wenn keine Features
if not alle_pta_features:
if not alle_pta_records:
prog.close()
QMessageBox.warning(
tab_widget,
@@ -1317,7 +1339,7 @@ def grenzpunkte_gemarkungsweise(
QMessageBox.warning(
tab_widget,
"Kein Referenzfeld",
f"{len(alle_pta_features)} PunktortTA-Objekte geladen, "
f"{len(alle_pta_records)} PunktortTA-Objekte geladen, "
f"aber kein Referenzfeld auf AX_Grenzpunkt gefunden.\n\n"
f"Gesuchte Feldnamen: {', '.join(_GEHOERT_ZU_KANDIDATEN)}\n"
f"Vorhandene Felder: {', '.join(pta_feld_namen)}",
@@ -1328,14 +1350,31 @@ def grenzpunkte_gemarkungsweise(
pr_pta = punktort_layer.dataProvider()
pr_pta.addAttributes([QgsField(n, QVariant.String) for n in pta_feld_namen if n])
punktort_layer.updateFields()
pr_pta.addFeatures(alle_pta_features)
# Features mit vollständig namensbasierter Attributzuweisung aufbauen –
# vermeidet Positions-Verschiebungen, die entstehen würden, wenn
# QgsFeatures aus tmp-Layern mit unterschiedlicher Feldreihenfolge
# positionsbasiert in punktort_layer übertragen werden.
neue_pta_features = []
from sn_basis.functions import QgsFeature as _QgsFeature
for record in alle_pta_records:
new_f = _QgsFeature(punktort_layer.fields())
new_f.setGeometry(record['geom'])
for n, val in record['attrs'].items():
if n in pta_feld_namen:
try:
new_f[n] = val
except Exception:
pass
neue_pta_features.append(new_f)
pr_pta.addFeatures(neue_pta_features)
punktort_layer.updateExtents()
alle_gp_ids: set[str] = set()
for ids in per_gemarkung_gp_ids.values():
alle_gp_ids.update(ids)
n_pta_gesamt = len(alle_pta_features)
n_pta_gesamt = len(alle_pta_records)
n_gp_ids = len(alle_gp_ids)
info(
"Grenzpunkte",