changed from three 1:N relations to a polymorphic relation

This commit is contained in:
David Spáčil
2026-03-16 14:00:37 +01:00
parent 9ec866f1d2
commit c17275ef66
+47 -29
View File
@@ -2,7 +2,7 @@
from qgis.gui import QgsMapToolIdentifyFeature from qgis.gui import QgsMapToolIdentifyFeature
from qgis.core import (QgsProject, QgsVectorLayer, QgsFeature, QgsGeometry, from qgis.core import (QgsProject, QgsVectorLayer, QgsFeature, QgsGeometry,
QgsField, QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsField, QgsCoordinateReferenceSystem, QgsCoordinateTransform,
QgsWkbTypes, QgsRelation, QgsEditorWidgetSetup, Qgis) QgsWkbTypes, QgsRelation, QgsPolymorphicRelation, QgsEditorWidgetSetup, Qgis)
from qgis.utils import iface from qgis.utils import iface
from qgis.PyQt.QtCore import Qt, QMetaType from qgis.PyQt.QtCore import Qt, QMetaType
from qgis.PyQt.QtWidgets import QMessageBox, QApplication from qgis.PyQt.QtWidgets import QMessageBox, QApplication
@@ -149,6 +149,7 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
# pian_lookup maps a Geometry ID (PIAN) to a list of its associated metadata # pian_lookup maps a Geometry ID (PIAN) to a list of its associated metadata
pian_lookup = {} pian_lookup = {}
komponenty_lookup = {}
target_pian_ids = set() target_pian_ids = set()
actions_with_geom = 0 actions_with_geom = 0
@@ -258,15 +259,15 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
if komponenty == "true": if komponenty == "true":
komps = dj.get('dj_komponenta', []) komps = dj.get('dj_komponenta', [])
for komp in komps: for komp in komps:
feat = QgsFeature() komp_temp = [
atributy = [
komp.get('ident_cely', ""), komp.get('ident_cely', ""),
dj_id,
komp.get('komponenta_areal', {}).get('value', ""), komp.get('komponenta_areal', {}).get('value', ""),
komp.get('komponenta_obdobi', {}).get('value', "") komp.get('komponenta_obdobi', {}).get('value', "")
] ]
feat.setAttributes(atributy) if dj_id not in komponenty_lookup:
feats_k.append(feat) komponenty_lookup[dj_id] = []
komponenty_lookup[dj_id].append(komp_temp)
if not target_pian_ids: if not target_pian_ids:
iface.messageBar().pushMessage("AMCR", f"Nalezeno {len(docs)} záznamů, ale žádný nemá geometrii.", level=Qgis.MessageLevel.Warning) iface.messageBar().pushMessage("AMCR", f"Nalezeno {len(docs)} záznamů, ale žádný nemá geometrii.", level=Qgis.MessageLevel.Warning)
@@ -374,14 +375,14 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
QgsField("komponenta", QMetaType.Type.QString), QgsField("komponenta", QMetaType.Type.QString),
QgsField("dj_id", QMetaType.Type.QString), QgsField("dj_id", QMetaType.Type.QString),
QgsField("komponenta_areal", QMetaType.Type.QString), QgsField("komponenta_areal", QMetaType.Type.QString),
QgsField("komponenta_obdobi", QMetaType.Type.QString) QgsField("komponenta_obdobi", QMetaType.Type.QString),
QgsField("vrstva", QMetaType.Type.QString)
] ]
pr.addAttributes(komponenty_cols) pr.addAttributes(komponenty_cols)
vl_komponenty.updateFields() vl_komponenty.updateFields()
idx_dj_id = vl_komponenty.fields().indexOf("dj_id") idx_vrstva = vl_komponenty.fields().indexOf("vrstva")
text_setup = QgsEditorWidgetSetup("TextEdit", {}) vl_komponenty.setEditorWidgetSetup(idx_vrstva, QgsEditorWidgetSetup("Hidden", {}))
vl_komponenty.setEditorWidgetSetup(idx_dj_id, text_setup)
for vl in layers: for vl in layers:
vl.dataProvider().addAttributes(cols) vl.dataProvider().addAttributes(cols)
@@ -429,11 +430,14 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
target_list = None target_list = None
if t == QgsWkbTypes.PolygonGeometry: if t == QgsWkbTypes.PolygonGeometry:
target_list = feats_p target_list = feats_p
referenced_layer = vl_poly
elif t == QgsWkbTypes.LineGeometry: elif t == QgsWkbTypes.LineGeometry:
target_list = feats_l target_list = feats_l
referenced_layer = vl_line
elif t == QgsWkbTypes.PointGeometry: elif t == QgsWkbTypes.PointGeometry:
target_list = feats_pt target_list = feats_pt
referenced_layer = vl_point
if target_list is None: if target_list is None:
continue continue
@@ -463,7 +467,12 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
meta['lokalita_typ'], meta['lokalita_druh'], meta['lokalita_typ'], meta['lokalita_druh'],
meta['lokalita_zachovalost'] meta['lokalita_zachovalost']
]) ])
if komponenty == "true" and meta['dj_id'] in komponenty_lookup:
for k in komponenty_lookup[meta['dj_id']]:
if len(k) == 3:
k.append(referenced_layer.id())
atributy.append(meta['pristupnost']) atributy.append(meta['pristupnost'])
feat.setAttributes(atributy) feat.setAttributes(atributy)
target_list.append(feat) target_list.append(feat)
@@ -471,6 +480,17 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
except Exception as ex: except Exception as ex:
print(f"Chyba při tvorbě feature: {ex}") print(f"Chyba při tvorbě feature: {ex}")
pass pass
if komponenty == "true":
for k in komponenty_lookup:
for komp in komponenty_lookup[k]:
if len(komp) == 4:
feat = QgsFeature()
atributy = [
komp[0], k, komp[1], komp[2], komp[3]
]
feat.setAttributes(atributy)
feats_k.append(feat)
# --- ADDING TO QGIS INTERFACE --- # --- ADDING TO QGIS INTERFACE ---
proj = QgsProject.instance() proj = QgsProject.instance()
@@ -499,24 +519,22 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
# --- RELATIONSHIP MANAGEMENT --- # --- RELATIONSHIP MANAGEMENT ---
# Set up automatic links between spatial layers and the component table # Set up automatic links between spatial layers and the component table
if komponenty == "true": if komponenty == "true":
parent_layers = [ parent_layers_ids = [vl_poly.id(), vl_line.id(), vl_point.id()]
(vl_poly, "Polygony"),
(vl_line, "Linie"),
(vl_point, "Body")
]
rel_manager = proj.relationManager() rel_manager = proj.relationManager()
for parent_layer, label in parent_layers:
rel = QgsRelation() rel = QgsPolymorphicRelation()
rel_name = f"Komponenty pro {label}" rel.setId(f"rel_komponenty_{archeologicky_zaznam}")
rel.setName(rel_name) rel.setName("Komponenty")
rel.setReferencingLayer(vl_komponenty.id()) rel.setReferencingLayer(vl_komponenty.id())
rel.setReferencedLayer(parent_layer.id()) rel.setReferencedLayerExpression("@layer_id")
rel.addFieldPair("dj_id", "Dokumentační jednotka") rel.setReferencedLayerField("vrstva")
rel.generateId() rel.setReferencedLayerIds(parent_layers_ids)
if rel.isValid(): rel.addFieldPair("dj_id", "Dokumentační jednotka")
rel_manager.addRelation(rel)
else: if rel.isValid():
print(f"Relace pro {label} není validní!") rel_manager.addPolymorphicRelation(rel)
else:
print("Relace Komponenty není validní!")
else: else:
iface.messageBar().pushMessage("AMCR", "Žádná data k zobrazení.", level=Qgis.MessageLevel.Info) iface.messageBar().pushMessage("AMCR", "Žádná data k zobrazení.", level=Qgis.MessageLevel.Info)