4 Commits

Author SHA1 Message Date
david 8c0c540fa4 Merge pull request #26 from ARUP-CAS/polymorphic-relation
Polymorphic relation instead of the standard ones; code cleanup
2026-03-16 14:13:50 +01:00
David Spáčil 8088b32661 removed unnecessary imports 2026-03-16 14:01:32 +01:00
David Spáčil c17275ef66 changed from three 1:N relations to a polymorphic relation 2026-03-16 14:00:37 +01:00
david 9ec866f1d2 Update metadata.txt 2026-03-13 10:56:09 +01:00
2 changed files with 49 additions and 34 deletions
+48 -33
View File
@@ -1,16 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
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, 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 QApplication
from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtGui import QCursor
import requests import requests
import json import json
import xml.etree.ElementTree as ET
import re
# Global cache to store translated terms from the Digital Archive # Global cache to store translated terms from the Digital Archive
TRANSLATIONS = {} TRANSLATIONS = {}
@@ -149,6 +146,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 +256,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 +372,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 +427,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 +464,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 +477,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 +516,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)
+1 -1
View File
@@ -6,7 +6,7 @@
[general] [general]
name=AMČR Viewer name=AMČR Viewer
qgisMinimumVersion=3.4.0 qgisMinimumVersion=3.4.0
qgisMaximumVersion=4.9.9 qgisMaximumVersion=4.99.0
description=Viewing and downloading the AMČR data. description=Viewing and downloading the AMČR data.
version=1.3.0 version=1.3.0
author=David Spáčil author=David Spáčil