mirror of
https://github.com/ARUP-CAS/aiscr-qgis-amcr-viewer.git
synced 2026-06-19 04:12:55 +02:00
Optimalizace výkonu a refaktorování GUI komponent (#22)
Comprehensive update to improve plugin efficiency and code quality: - Performance: Increased BATCH_PIAN to 200 and optimized attribute parsing loops. - Performance: Optimized codelist caching to reload only necessary data. - UI/UX: Fixed plugin unloading (toolbar icon duplication) and added safe cursor handling. - Refactoring: Moved GUI helper methods to class level for better OOP structure. - Modernization: Updated dialog execution syntax to modern PyQt5/6 standards. - Documentation: Added full inline English documentation across all modules.
This commit is contained in:
+166
-128
@@ -11,11 +11,11 @@ import json
|
||||
import xml.etree.ElementTree as ET
|
||||
import re
|
||||
|
||||
# Global translations cache
|
||||
# Global cache to store translated terms from the Digital Archive
|
||||
TRANSLATIONS = {}
|
||||
|
||||
# Download Digiarchive's vocabulary
|
||||
def load_translations():
|
||||
"""Fetches the official Czech translation dictionary from the AISCR API."""
|
||||
global TRANSLATIONS
|
||||
if TRANSLATIONS:
|
||||
return
|
||||
@@ -26,22 +26,32 @@ def load_translations():
|
||||
if r.status_code == 200:
|
||||
TRANSLATIONS = r.json()
|
||||
except Exception as e:
|
||||
print(f"Chyba při stahování hesláře: {e}")
|
||||
print(f"Error downloading vocabulary: {e}")
|
||||
|
||||
def tr_code(code):
|
||||
"""Translates a technical code into a human-readable string using the global cache."""
|
||||
if not code:
|
||||
return ""
|
||||
return TRANSLATIONS.get(code, code)
|
||||
|
||||
def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false"):
|
||||
"""
|
||||
Main processing function:
|
||||
1. Determines search area (Bounding Box)
|
||||
2. Fetches metadata and geometries from API
|
||||
3. Creates QGIS memory layers and populates them with features
|
||||
"""
|
||||
load_translations()
|
||||
|
||||
# 1. Bounding box
|
||||
# --- 1. COORDINATE TRANSFORMATION ---
|
||||
# Get current map extent and transform it from project CRS (usually S-JTSK) to WGS-84 for the API
|
||||
extent = canvas.extent()
|
||||
crs_src = canvas.mapSettings().destinationCrs()
|
||||
crs_dest = QgsCoordinateReferenceSystem("EPSG:4326")
|
||||
xform = QgsCoordinateTransform(crs_src, crs_dest, QgsProject.instance())
|
||||
extent_wgs = xform.transformBoundingBox(extent)
|
||||
|
||||
# Format the bounding box string as required by the API: minLat,minLon,maxLat,maxLon
|
||||
bbox_str = f"{extent_wgs.yMinimum()},{extent_wgs.xMinimum()},{extent_wgs.yMaximum()},{extent_wgs.xMaximum()}"
|
||||
|
||||
url = "https://digiarchiv.aiscr.cz/api/search/query"
|
||||
@@ -50,21 +60,21 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
|
||||
try:
|
||||
# ===================
|
||||
# A) METADATA (Fieldwork event/Site)
|
||||
# ===================
|
||||
# ==========================================
|
||||
# A) METADATA FETCHING (Fieldwork/Site)
|
||||
# ==========================================
|
||||
|
||||
base_params = {
|
||||
"mapa": "true",
|
||||
"sort": "ident_cely asc"
|
||||
"sort": "ident_cely asc",
|
||||
"entity": typ_dat
|
||||
}
|
||||
|
||||
base_params["entity"] = typ_dat
|
||||
|
||||
# Restrict search to map window if requested
|
||||
if bb == "true":
|
||||
base_params["loc_rpt"] = bbox_str
|
||||
|
||||
# Apply filters
|
||||
# Apply multi-select filters from the dialog using the ':or' syntax required by the API
|
||||
if filters:
|
||||
for key, value in filters.items():
|
||||
if not value:
|
||||
@@ -76,13 +86,17 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
|
||||
docs = []
|
||||
current_page = 0
|
||||
BATCH_DOCS = 500
|
||||
MAX_LIMIT = 20000
|
||||
feats_k = []
|
||||
BATCH_DOCS = 500 # Records per API request
|
||||
MAX_LIMIT = 20000 # Safety limit to prevent QGIS from freezing
|
||||
feats_k = [] # List for component features (non-spatial)
|
||||
|
||||
seen_ids = set()
|
||||
target_pian_ids_count = 0
|
||||
|
||||
# Check if we should skip negative results based on filter
|
||||
skip_negativni = filters.get('posevidence') == 'true' if filters else False
|
||||
|
||||
# --- API PAGINATION LOOP ---
|
||||
while True:
|
||||
base_params['rows'] = BATCH_DOCS
|
||||
if current_page > 0:
|
||||
@@ -100,6 +114,7 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
if not batch_docs:
|
||||
break
|
||||
|
||||
# Filter out duplicates and append to main list
|
||||
new_docs = []
|
||||
for d in batch_docs:
|
||||
ident = d.get('ident_cely')
|
||||
@@ -117,7 +132,7 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
break
|
||||
|
||||
current_page += 1
|
||||
QApplication.processEvents()
|
||||
QApplication.processEvents() # Keep UI responsive
|
||||
|
||||
except Exception as e:
|
||||
print(f"Chyba při stránkování na straně {current_page}: {e}")
|
||||
@@ -128,12 +143,31 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
return
|
||||
|
||||
# ==========================================
|
||||
# Attribute parsing
|
||||
# B) ATTRIBUTE PARSING
|
||||
# ==========================================
|
||||
|
||||
# pian_lookup maps a Geometry ID (PIAN) to a list of its associated metadata
|
||||
pian_lookup = {}
|
||||
target_pian_ids = set()
|
||||
actions_with_geom = 0
|
||||
|
||||
# Helper function for safe single-value extraction
|
||||
def g(doc, key, default=""):
|
||||
val = doc.get(key)
|
||||
if isinstance(val, list):
|
||||
return str(val[0]) if val else default
|
||||
return str(val) if val is not None else default
|
||||
|
||||
# Helper function for safe list-value extraction and joining
|
||||
def g_list(doc, key, translate=False):
|
||||
val = doc.get(key, [])
|
||||
if not isinstance(val, list):
|
||||
val = [val] if val else []
|
||||
if translate:
|
||||
return ", ".join([tr_code(str(x)) for x in val if x])
|
||||
return ", ".join([str(x) for x in val if x])
|
||||
|
||||
# Process each downloaded metadata record
|
||||
for doc in docs:
|
||||
piani = doc.get('az_dj_pian', [])
|
||||
if not piani:
|
||||
@@ -141,23 +175,11 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
|
||||
actions_with_geom += 1
|
||||
|
||||
def g(key, default=""):
|
||||
val = doc.get(key)
|
||||
if isinstance(val, list):
|
||||
return str(val[0]) if val else default
|
||||
return str(val) if val is not None else default
|
||||
|
||||
def g_list(key, translate=False):
|
||||
val = doc.get(key, [])
|
||||
if not isinstance(val, list):
|
||||
val = [val] if val else []
|
||||
if translate:
|
||||
return ", ".join([tr_code(str(x)) for x in val if x])
|
||||
return ", ".join([str(x) for x in val if x])
|
||||
|
||||
# Extract protected data (fields not available in public Solr index)
|
||||
az_chranene = doc.get('az_chranene_udaje', {})
|
||||
chranene = doc.get('akce_chranene_udaje') or doc.get('lokalita_chranene_udaje') or {}
|
||||
|
||||
# Format additional cadastral areas from dictionaries
|
||||
dalsi_kat = az_chranene.get('dalsi_katastr', [])
|
||||
dalsi_kat_str = ""
|
||||
if isinstance(dalsi_kat, list):
|
||||
@@ -168,25 +190,26 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
lokalita_nazev = chranene.get('nazev', "")
|
||||
lokalita_popis = chranene.get('popis', "")
|
||||
|
||||
# Prepate common metadata
|
||||
# Core metadata structure
|
||||
meta = {
|
||||
"ident_cely": doc.get('ident_cely', ''),
|
||||
"az_okres": g('az_okres'),
|
||||
"katastr": g_list('katastr'),
|
||||
"az_okres": g(doc, 'az_okres'),
|
||||
"katastr": g_list(doc, 'katastr'),
|
||||
"dalsi_katastr": dalsi_kat_str,
|
||||
"pristupnost": g('pristupnost'),
|
||||
"loc": g_list('loc')
|
||||
"pristupnost": g(doc, 'pristupnost'),
|
||||
"loc": g_list(doc, 'loc')
|
||||
}
|
||||
|
||||
# Add entity-specific metadata
|
||||
if typ_dat == "akce":
|
||||
meta.update({
|
||||
"akce_hlavni_vedouci": g('akce_hlavni_vedouci'),
|
||||
"akce_organizace": tr_code(g('akce_organizace')),
|
||||
"akce_specifikace_data": tr_code(g('akce_specifikace_data')),
|
||||
"akce_datum_zahajeni": g('akce_datum_zahajeni'),
|
||||
"akce_datum_ukonceni": g('akce_datum_ukonceni'),
|
||||
"akce_hlavni_typ": tr_code(g('akce_hlavni_typ')),
|
||||
"akce_vedlejsi_typ": g_list('akce_vedlejsi_typ', translate=True),
|
||||
"akce_hlavni_vedouci": g(doc, 'akce_hlavni_vedouci'),
|
||||
"akce_organizace": tr_code(g(doc, 'akce_organizace')),
|
||||
"akce_specifikace_data": tr_code(g(doc, 'akce_specifikace_data')),
|
||||
"akce_datum_zahajeni": g(doc, 'akce_datum_zahajeni'),
|
||||
"akce_datum_ukonceni": g(doc, 'akce_datum_ukonceni'),
|
||||
"akce_hlavni_typ": tr_code(g(doc, 'akce_hlavni_typ')),
|
||||
"akce_vedlejsi_typ": g_list(doc, 'akce_vedlejsi_typ', translate=True),
|
||||
"lokalizace_okolnosti": str(lokalizace) if lokalizace else "",
|
||||
"akce_je_nz": "Ano" if doc.get('akce_je_nz') is True else "Ne",
|
||||
})
|
||||
@@ -195,33 +218,42 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
meta.update({
|
||||
"lokalita_nazev": lokalita_nazev,
|
||||
"lokalita_popis": lokalita_popis,
|
||||
"lokalita_zachovalost": tr_code(g('lokalita_zachovalost')),
|
||||
"lokalita_druh": tr_code(g('lokalita_druh')),
|
||||
"lokalita_typ": tr_code(g('lokalita_typ_lokality')),
|
||||
"lokalita_zachovalost": tr_code(g(doc, 'lokalita_zachovalost')),
|
||||
"lokalita_druh": tr_code(g(doc, 'lokalita_druh')),
|
||||
"lokalita_typ": tr_code(g(doc, 'lokalita_typ_lokality')),
|
||||
})
|
||||
|
||||
# Documentation units (DJ) within the record
|
||||
djs = doc.get('az_dokumentacni_jednotka', [])
|
||||
|
||||
for dj in djs:
|
||||
if filters and filters.get('posevidence') == 'true' and dj.get('dj_negativni_jednotka') is True:
|
||||
# Filter out negative evidence units if requested
|
||||
if skip_negativni and dj.get('dj_negativni_jednotka') is True:
|
||||
continue
|
||||
|
||||
dj_meta = meta.copy()
|
||||
dj_id = dj.get('ident_cely')
|
||||
dj_meta['dj_id'] = dj_id
|
||||
dj_typ = dj.get('dj_typ')
|
||||
dj_meta['dj_typ_value'] = dj_typ.get('value') if dj_typ else ""
|
||||
dj_meta['dj_negativni'] = "Negativní" if dj.get('dj_negativni_jednotka') is True else "Pozitivní"
|
||||
|
||||
# Merge general meta with documentation unit specific data
|
||||
dj_meta = {
|
||||
**meta,
|
||||
'dj_id': dj_id,
|
||||
'dj_typ_value': dj_typ.get('value') if dj_typ else "",
|
||||
'dj_negativni': "Negativní" if dj.get('dj_negativni_jednotka') is True else "Pozitivní"
|
||||
}
|
||||
|
||||
# Link Documentation Unit to Geometry (PIAN)
|
||||
dj_pian = dj.get('dj_pian')
|
||||
if dj_pian:
|
||||
dj_pian_value = dj_pian.get('id')
|
||||
if dj_pian_value:
|
||||
target_pian_ids.add(dj_pian_value)
|
||||
target_pian_ids_count = target_pian_ids_count+1
|
||||
target_pian_ids_count += 1
|
||||
if dj_pian_value not in pian_lookup:
|
||||
pian_lookup[dj_pian_value] = []
|
||||
pian_lookup[dj_pian_value].append(dj_meta)
|
||||
|
||||
# Parse non-spatial components if requested (for relational tables)
|
||||
if komponenty == "true":
|
||||
komps = dj.get('dj_komponenta', [])
|
||||
for komp in komps:
|
||||
@@ -229,7 +261,6 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
atributy = [
|
||||
komp.get('ident_cely', ""),
|
||||
dj_id,
|
||||
# komponenta_aktivita ..?,
|
||||
komp.get('komponenta_areal', {}).get('value', ""),
|
||||
komp.get('komponenta_obdobi', {}).get('value', "")
|
||||
]
|
||||
@@ -242,16 +273,15 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
|
||||
|
||||
# ==========================================
|
||||
# B) Geometry (PIAN)
|
||||
# C) GEOMETRY FETCHING (PIAN)
|
||||
# ==========================================
|
||||
ids_list = list(target_pian_ids)
|
||||
total_pians = len(ids_list)
|
||||
docs_pian = []
|
||||
BATCH_PIAN = 50
|
||||
BATCH_PIAN = 200 # Geometry requests are batch-processed to stay under URL length limits
|
||||
|
||||
iface.messageBar().pushMessage("AMCR", f"Záznamů: {len(docs)} (z toho {actions_with_geom} s mapou). Stahuji {total_pians} unikátních geometrií, vykresluji {target_pian_ids_count} geometrií...", level=1)
|
||||
|
||||
# Seznam polí pro PIAN
|
||||
fl_pian = ["ident_cely", "pian_typ", "pian_chranene_udaje", "pian_presnost"]
|
||||
|
||||
for i in range(0, total_pians, BATCH_PIAN):
|
||||
@@ -275,19 +305,18 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
print(f"Chyba PIAN: {e}")
|
||||
|
||||
# ==========================================
|
||||
# C) TVORBA VRSTEV
|
||||
# D) LAYER CREATION (QGIS Memory Layers)
|
||||
# ==========================================
|
||||
vl_poly = QgsVectorLayer("Polygon?crs=epsg:5514", "AMCR Plochy", "memory")
|
||||
vl_line = QgsVectorLayer("LineString?crs=epsg:5514", "AMCR Linie", "memory")
|
||||
vl_point = QgsVectorLayer("Point?crs=epsg:5514", "AMCR Body", "memory")
|
||||
layers = [vl_poly, vl_line, vl_point]
|
||||
|
||||
if typ_dat == "akce":
|
||||
archeologicky_zaznam = "Akce"
|
||||
elif typ_dat == "lokalita":
|
||||
archeologicky_zaznam = "Lokalita"
|
||||
archeologicky_zaznam = "Akce" if typ_dat == "akce" else "Lokalita"
|
||||
|
||||
# Definice sloupců atributové tabulky
|
||||
# Initialize three layers for different geometry types (S-JTSK CRS)
|
||||
vl_poly = QgsVectorLayer("Polygon?crs=epsg:5514", f"AMCR_{archeologicky_zaznam}_Polygony", "memory")
|
||||
vl_line = QgsVectorLayer("LineString?crs=epsg:5514", f"AMCR_{archeologicky_zaznam}_Linie", "memory")
|
||||
vl_point = QgsVectorLayer("Point?crs=epsg:5514", f"AMCR_{archeologicky_zaznam}_Body", "memory")
|
||||
layers = [vl_poly, vl_line, vl_point]
|
||||
|
||||
# Define attribute table structure
|
||||
cols = [
|
||||
QgsField("PIAN", QVariant.String),
|
||||
QgsField("Přesnost", QVariant.String),
|
||||
@@ -302,8 +331,10 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
QgsField("Další katastry", QVariant.String)
|
||||
]
|
||||
|
||||
# Extend table based on data type
|
||||
if typ_dat == "akce":
|
||||
cols += [
|
||||
QgsField("Akce – lokalizace", QVariant.String),
|
||||
QgsField("Vedoucí akce", QVariant.String),
|
||||
QgsField("Organizace", QVariant.String),
|
||||
QgsField("Specifikace data", QVariant.String),
|
||||
@@ -311,28 +342,36 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
QgsField("Datum ukončení", QVariant.String),
|
||||
QgsField("Hlavní typ", QVariant.String),
|
||||
QgsField("Vedlejší typ", QVariant.String),
|
||||
QgsField("Zjištění", QVariant.String),
|
||||
QgsField("Akce – lokalizace", QVariant.String),
|
||||
QgsField("Zjištění", QVariant.String),
|
||||
QgsField("Akce – nahrazuje NZ", QVariant.String),
|
||||
]
|
||||
elif typ_dat == "lokalita":
|
||||
cols += [
|
||||
QgsField("Název lokality", QVariant.String),
|
||||
QgsField("Popis lokality", QVariant.String),
|
||||
QgsField("Typ lokality", QVariant.String),
|
||||
QgsField("Druh lokality", QVariant.String),
|
||||
QgsField("Zachovalost", QVariant.String)
|
||||
QgsField("nazev_lokality", QVariant.String),
|
||||
QgsField("popis_lokality", QVariant.String),
|
||||
QgsField("typ_lokality", QVariant.String),
|
||||
QgsField("druh_lokality", QVariant.String),
|
||||
QgsField("zachovalost", QVariant.String)
|
||||
]
|
||||
|
||||
cols.append(QgsField("Přístupnost", QVariant.String))
|
||||
|
||||
# Use aliases for technical field names
|
||||
alias_map = {
|
||||
"nazev_lokality": "Název lokality",
|
||||
"popis_lokality": "Popis lokality",
|
||||
"typ_lokality": "Typ lokality",
|
||||
"druh_lokality": "Druh lokality",
|
||||
"zachovalost": "Zachovalost"
|
||||
}
|
||||
|
||||
# Create a non-spatial table for components if requested
|
||||
if komponenty == "true":
|
||||
vl_komponenty = QgsVectorLayer("None", "AMCR Komponenty", "memory")
|
||||
pr = vl_komponenty.dataProvider()
|
||||
komponenty_cols = [
|
||||
QgsField("komponenta", QVariant.String), # ident_cely
|
||||
QgsField("komponenta", QVariant.String),
|
||||
QgsField("dj_id", QVariant.String),
|
||||
# potenciálně QgsField("komponenta_aktivita", QVariant.String),
|
||||
QgsField("komponenta_areal", QVariant.String),
|
||||
QgsField("komponenta_obdobi", QVariant.String)
|
||||
]
|
||||
@@ -346,98 +385,97 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
for vl in layers:
|
||||
vl.dataProvider().addAttributes(cols)
|
||||
vl.updateFields()
|
||||
for tech_name, alias in alias_map.items():
|
||||
idx = vl.fields().lookupField(tech_name)
|
||||
if idx != -1:
|
||||
vl.setFieldAlias(idx, alias)
|
||||
|
||||
# Lists to hold features before batch-adding to layers
|
||||
feats_p, feats_l, feats_pt = [], [], []
|
||||
|
||||
# --- FEATURE POPULATION ---
|
||||
for doc in docs_pian:
|
||||
try:
|
||||
pid = doc.get('ident_cely', '')
|
||||
if pid not in pian_lookup:
|
||||
continue
|
||||
|
||||
|
||||
metas = pian_lookup[pid]
|
||||
|
||||
# Geometry processing
|
||||
# Extract WKT geometry from protected JSON data
|
||||
raw = doc.get('pian_chranene_udaje')
|
||||
if isinstance(raw, list) and raw:
|
||||
raw = raw[0]
|
||||
jdata = json.loads(raw) if isinstance(raw, str) else (raw if isinstance(raw, dict) else {})
|
||||
jdata = json.loads(raw) if isinstance(raw, str) else (raw or {})
|
||||
|
||||
wkt = None
|
||||
if jdata.get('geom_sjtsk_wkt'):
|
||||
wkt = jdata['geom_sjtsk_wkt'].get('value')
|
||||
wkt = jdata.get('geom_sjtsk_wkt', {}).get('value')
|
||||
elif jdata.get('geom_wkt'):
|
||||
wkt = jdata['geom_wkt'].get('value')
|
||||
wkt = jdata.get('geom_wkt', {}).get('value')
|
||||
|
||||
# PIAN attributes
|
||||
pian_presnost = tr_code(str(doc.get('pian_presnost', '')))
|
||||
pian_typ = tr_code(str(doc.get('pian_typ', '')))
|
||||
|
||||
# Final precision filter check
|
||||
if filters and filters.get('f_pian_presnost') and doc.get('pian_presnost') not in filters.get('f_pian_presnost'):
|
||||
continue
|
||||
|
||||
if wkt:
|
||||
geom = QgsGeometry.fromWkt(wkt)
|
||||
if geom.isGeosValid():
|
||||
t = geom.type()
|
||||
target_list = None
|
||||
if t == QgsWkbTypes.PolygonGeometry:
|
||||
target_list = feats_p
|
||||
elif t == QgsWkbTypes.LineGeometry:
|
||||
target_list = feats_l
|
||||
elif t == QgsWkbTypes.PointGeometry:
|
||||
target_list = feats_pt
|
||||
|
||||
if target_list is None:
|
||||
continue
|
||||
|
||||
is_akce = (typ_dat == "akce")
|
||||
|
||||
# Create a QGIS feature for each documentation unit associated with this geometry
|
||||
for meta in metas:
|
||||
feat = QgsFeature()
|
||||
feat.setGeometry(geom)
|
||||
atributy = [
|
||||
pid,
|
||||
pian_presnost,
|
||||
pian_typ,
|
||||
meta['dj_id'],
|
||||
meta['dj_typ_value'],
|
||||
meta['loc'],
|
||||
meta['ident_cely'],
|
||||
pid, pian_presnost, pian_typ, meta['dj_id'],
|
||||
meta['dj_typ_value'], meta['loc'], meta['ident_cely'],
|
||||
"https://digiarchiv.aiscr.cz/id/" + meta['ident_cely'],
|
||||
meta['az_okres'],
|
||||
meta['katastr'],
|
||||
meta['dalsi_katastr']
|
||||
meta['az_okres'], meta['katastr'], meta['dalsi_katastr']
|
||||
]
|
||||
if typ_dat == "akce":
|
||||
atributy += [
|
||||
meta['akce_hlavni_vedouci'],
|
||||
meta['akce_organizace'],
|
||||
meta['akce_specifikace_data'],
|
||||
meta['akce_datum_zahajeni'],
|
||||
meta['akce_datum_ukonceni'],
|
||||
meta['akce_hlavni_typ'],
|
||||
meta['akce_vedlejsi_typ'],
|
||||
meta['dj_negativni'],
|
||||
meta['lokalizace_okolnosti'],
|
||||
meta['akce_je_nz']
|
||||
]
|
||||
|
||||
elif typ_dat == "lokalita":
|
||||
atributy += [
|
||||
meta['lokalita_nazev'],
|
||||
meta['lokalita_popis'],
|
||||
meta['lokalita_typ'],
|
||||
meta['lokalita_druh'],
|
||||
if is_akce:
|
||||
atributy.extend([
|
||||
meta['lokalizace_okolnosti'], meta['akce_hlavni_vedouci'],
|
||||
meta['akce_organizace'], meta['akce_specifikace_data'],
|
||||
meta['akce_datum_zahajeni'], meta['akce_datum_ukonceni'],
|
||||
meta['akce_hlavni_typ'], meta['akce_vedlejsi_typ'],
|
||||
meta['dj_negativni'], meta['akce_je_nz']
|
||||
])
|
||||
else:
|
||||
atributy.extend([
|
||||
meta['lokalita_nazev'], meta['lokalita_popis'],
|
||||
meta['lokalita_typ'], meta['lokalita_druh'],
|
||||
meta['lokalita_zachovalost']
|
||||
]
|
||||
])
|
||||
|
||||
atributy.append(meta['pristupnost'])
|
||||
|
||||
feat.setAttributes(atributy)
|
||||
|
||||
t = geom.type()
|
||||
if t == QgsWkbTypes.PolygonGeometry:
|
||||
feats_p.append(feat)
|
||||
elif t == QgsWkbTypes.LineGeometry:
|
||||
feats_l.append(feat)
|
||||
elif t == QgsWkbTypes.PointGeometry:
|
||||
feats_pt.append(feat)
|
||||
target_list.append(feat)
|
||||
|
||||
except Exception as ex:
|
||||
print(f"Chyba při tvorbě feature: {ex}")
|
||||
pass
|
||||
|
||||
# --- ADDING TO QGIS INTERFACE ---
|
||||
proj = QgsProject.instance()
|
||||
added = 0
|
||||
layers_to_process = [
|
||||
(feats_p, vl_poly, "Plochy"),
|
||||
(feats_p, vl_poly, "Polygony"),
|
||||
(feats_l, vl_line, "Linie"),
|
||||
(feats_pt, vl_point, "Body"),
|
||||
]
|
||||
@@ -449,7 +487,7 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
if f:
|
||||
l.dataProvider().addFeatures(f)
|
||||
l.updateExtents()
|
||||
l.setName(f"AMČR {n} (Filtrováno)")
|
||||
l.setName(f"AMCR_{archeologicky_zaznam}_{n}")
|
||||
proj.addMapLayer(l)
|
||||
if n != "Komponenty":
|
||||
added += len(f)
|
||||
@@ -457,23 +495,22 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
if added > 0:
|
||||
iface.messageBar().pushMessage("AMCR", f"Hotovo. Záznamů: {len(docs)} (s geom: {actions_with_geom}). Vykresleno: {added} prvků.", level=0)
|
||||
|
||||
# Relation
|
||||
# --- RELATIONSHIP MANAGEMENT ---
|
||||
# Set up automatic links between spatial layers and the component table
|
||||
if komponenty == "true":
|
||||
parent_layers = [
|
||||
(vl_poly, "Plochy"),
|
||||
(vl_poly, "Polygony"),
|
||||
(vl_line, "Linie"),
|
||||
(vl_point, "Body")
|
||||
]
|
||||
rel_manager = proj.relationManager()
|
||||
for parent_layer, label in parent_layers:
|
||||
rel = QgsRelation()
|
||||
#rel_id = f"rel_{parent_layer.id()}_komponenty"
|
||||
rel_name = f"Komponenty pro {label}"
|
||||
#rel.setId(rel_id)
|
||||
rel.setName(rel_name)
|
||||
rel.setReferencingLayer(vl_komponenty.id())
|
||||
rel.setReferencedLayer(parent_layer.id())
|
||||
rel.addFieldPair("dj_id", "Dokumentační jednotka") # Upravit název parent sloupce po změně názvů sloupců u vrstev akcí/lokalit
|
||||
rel.addFieldPair("dj_id", "Dokumentační jednotka")
|
||||
rel.generateId()
|
||||
if rel.isValid():
|
||||
rel_manager.addRelation(rel)
|
||||
@@ -486,4 +523,5 @@ def load_amcr_data(canvas, bb, filters=None, typ_dat="akce", komponenty="false")
|
||||
except Exception as e:
|
||||
iface.messageBar().pushMessage("Chyba", str(e), level=2)
|
||||
finally:
|
||||
QApplication.restoreOverrideCursor()
|
||||
# Always restore cursor, even after failure
|
||||
QApplication.restoreOverrideCursor()
|
||||
Reference in New Issue
Block a user