mirror of
https://github.com/ARUP-CAS/aiscr-qgis-amcr-viewer.git
synced 2026-10-12 22:07:34 +02:00
feature (wip): první krůčky logiky pro parsování PAS záznamů
- dosavadní logika parsování platná pro akce a lokality je podmíněna typ_dat - stub logiky parsování pro samostatné nálezy
This commit is contained in:
1 parent
27a0f4e9ea
commit
2ab3ace310
1 file changed
+253
-240
+253
-240
@@ -451,270 +451,283 @@ def load_amcr_data(canvas, bb, filters=None,
|
|||||||
return ", ".join([str(x) for x in val if x])
|
return ", ".join([str(x) for x in val if x])
|
||||||
|
|
||||||
# Process each downloaded metadata record
|
# Process each downloaded metadata record
|
||||||
for doc in docs:
|
if typ_dat in archeologicky_zaznam_l:
|
||||||
piani = doc.get('az_dj_pian', [])
|
for doc in docs:
|
||||||
if not piani:
|
piani = doc.get('az_dj_pian', [])
|
||||||
continue
|
if not piani:
|
||||||
|
|
||||||
if only_projektove_akce and not doc.get("akce_projekt", False):
|
|
||||||
continue
|
|
||||||
|
|
||||||
actions_with_geom += 1
|
|
||||||
|
|
||||||
# Extract protected fields ('or {}' – key may hold None)
|
|
||||||
az_chranene = doc.get('az_chranene_udaje') or {}
|
|
||||||
chranene = (
|
|
||||||
doc.get('akce_chranene_udaje')
|
|
||||||
or doc.get('lokalita_chranene_udaje')
|
|
||||||
or {}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Format additional cadastral areas from nested dicts
|
|
||||||
dalsi_kat = az_chranene.get('dalsi_katastr', [])
|
|
||||||
dalsi_kat_str = ""
|
|
||||||
if isinstance(dalsi_kat, list):
|
|
||||||
items = [
|
|
||||||
x.get('value', '') if isinstance(x, dict) else str(x)
|
|
||||||
for x in dalsi_kat
|
|
||||||
]
|
|
||||||
dalsi_kat_str = ", ".join([i for i in items if i])
|
|
||||||
|
|
||||||
lokalizace = chranene.get('lokalizace_okolnosti', "")
|
|
||||||
lokalita_nazev = chranene.get('nazev', "")
|
|
||||||
lokalita_popis = chranene.get('popis', "")
|
|
||||||
|
|
||||||
# Core metadata structure
|
|
||||||
meta = {
|
|
||||||
"ident_cely": doc.get('ident_cely', ''),
|
|
||||||
"az_okres": g(doc, 'az_okres'),
|
|
||||||
"katastr": g_list(doc, 'katastr'),
|
|
||||||
"dalsi_katastr": dalsi_kat_str,
|
|
||||||
"pristupnost": g(doc, 'pristupnost'),
|
|
||||||
"loc": g_list(doc, 'loc'),
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add entity-specific metadata
|
|
||||||
if typ_dat == "akce":
|
|
||||||
meta.update({
|
|
||||||
"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"
|
|
||||||
),
|
|
||||||
"projekt": g(
|
|
||||||
doc,
|
|
||||||
'akce_projekt',
|
|
||||||
""
|
|
||||||
),
|
|
||||||
})
|
|
||||||
|
|
||||||
elif typ_dat == "lokalita":
|
|
||||||
meta.update({
|
|
||||||
"lokalita_nazev": lokalita_nazev,
|
|
||||||
"lokalita_popis": lokalita_popis,
|
|
||||||
"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:
|
|
||||||
# Skip negative evidence units if requested
|
|
||||||
if skip_negativni and dj.get('dj_negativni_jednotka') is True:
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
komps = dj.get('dj_komponenta', [])
|
if only_projektove_akce and not doc.get("akce_projekt", False):
|
||||||
|
continue
|
||||||
|
|
||||||
if filter_areal or filter_datace:
|
actions_with_geom += 1
|
||||||
if not komps:
|
|
||||||
continue
|
|
||||||
if not any(
|
|
||||||
komp_projde_filtrem(
|
|
||||||
komp, filter_areal,
|
|
||||||
filter_datace, filters
|
|
||||||
)
|
|
||||||
for komp in komps
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
dj_id = dj.get('ident_cely')
|
# Extract protected fields ('or {}' – key may hold None)
|
||||||
dj_typ = dj.get('dj_typ')
|
az_chranene = doc.get('az_chranene_udaje') or {}
|
||||||
|
chranene = (
|
||||||
|
doc.get('akce_chranene_udaje')
|
||||||
|
or doc.get('lokalita_chranene_udaje')
|
||||||
|
or {}
|
||||||
|
)
|
||||||
|
|
||||||
# Merge shared metadata with documentation unit-specific fields
|
# Format additional cadastral areas from nested dicts
|
||||||
dj_meta = {
|
dalsi_kat = az_chranene.get('dalsi_katastr', [])
|
||||||
**meta,
|
dalsi_kat_str = ""
|
||||||
'dj_id': dj_id,
|
if isinstance(dalsi_kat, list):
|
||||||
'dj_typ_value': dj_typ.get('value') if dj_typ else "",
|
items = [
|
||||||
'dj_negativni': (
|
x.get('value', '') if isinstance(x, dict) else str(x)
|
||||||
"Negativní"
|
for x in dalsi_kat
|
||||||
if dj.get('dj_negativni_jednotka') is True
|
]
|
||||||
else "Pozitivní"
|
dalsi_kat_str = ", ".join([i for i in items if i])
|
||||||
)
|
|
||||||
|
lokalizace = chranene.get('lokalizace_okolnosti', "")
|
||||||
|
lokalita_nazev = chranene.get('nazev', "")
|
||||||
|
lokalita_popis = chranene.get('popis', "")
|
||||||
|
|
||||||
|
# Core metadata structure
|
||||||
|
meta = {
|
||||||
|
"ident_cely": doc.get('ident_cely', ''),
|
||||||
|
"az_okres": g(doc, 'az_okres'),
|
||||||
|
"katastr": g_list(doc, 'katastr'),
|
||||||
|
"dalsi_katastr": dalsi_kat_str,
|
||||||
|
"pristupnost": g(doc, 'pristupnost'),
|
||||||
|
"loc": g_list(doc, 'loc'),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Link Documentation Unit to Geometry (PIAN)
|
# Add entity-specific metadata
|
||||||
dj_pian = dj.get('dj_pian')
|
if typ_dat == "akce":
|
||||||
if dj_pian:
|
meta.update({
|
||||||
dj_pian_value = dj_pian.get('id')
|
"akce_hlavni_vedouci": g(
|
||||||
if dj_pian_value:
|
doc,
|
||||||
target_pian_ids.add(dj_pian_value)
|
'akce_hlavni_vedouci'
|
||||||
if dj_pian_value not in pian_lookup:
|
),
|
||||||
pian_lookup[dj_pian_value] = []
|
"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"
|
||||||
|
),
|
||||||
|
"projekt": g(
|
||||||
|
doc,
|
||||||
|
'akce_projekt',
|
||||||
|
""
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
if komponenty == "true":
|
elif typ_dat == "lokalita":
|
||||||
# One feature per component –
|
meta.update({
|
||||||
# all data on a single row, no relations needed
|
"lokalita_nazev": lokalita_nazev,
|
||||||
if komps:
|
"lokalita_popis": lokalita_popis,
|
||||||
for komp in komps:
|
"lokalita_zachovalost": tr_code(g(
|
||||||
if not komp_projde_filtrem(
|
doc,
|
||||||
komp, filter_areal,
|
'lokalita_zachovalost'
|
||||||
filter_datace, filters
|
)),
|
||||||
):
|
"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:
|
||||||
|
# Skip negative evidence units if requested
|
||||||
|
if skip_negativni and dj.get('dj_negativni_jednotka') is True:
|
||||||
|
continue
|
||||||
|
|
||||||
|
komps = dj.get('dj_komponenta', [])
|
||||||
|
|
||||||
|
if filter_areal or filter_datace:
|
||||||
|
if not komps:
|
||||||
|
continue
|
||||||
|
if not any(
|
||||||
|
komp_projde_filtrem(
|
||||||
|
komp, filter_areal,
|
||||||
|
filter_datace, filters
|
||||||
|
)
|
||||||
|
for komp in komps
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
|
dj_id = dj.get('ident_cely')
|
||||||
|
dj_typ = dj.get('dj_typ')
|
||||||
|
|
||||||
|
# Merge shared metadata with documentation unit-specific fields
|
||||||
|
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)
|
||||||
|
if dj_pian_value not in pian_lookup:
|
||||||
|
pian_lookup[dj_pian_value] = []
|
||||||
|
|
||||||
|
if komponenty == "true":
|
||||||
|
# One feature per component –
|
||||||
|
# all data on a single row, no relations needed
|
||||||
|
if komps:
|
||||||
|
for komp in komps:
|
||||||
|
if not komp_projde_filtrem(
|
||||||
|
komp, filter_areal,
|
||||||
|
filter_datace, filters
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
|
komp_meta = {
|
||||||
|
**dj_meta,
|
||||||
|
'komponenta_id': komp.get(
|
||||||
|
'ident_cely',
|
||||||
|
""
|
||||||
|
),
|
||||||
|
'komponenta_areal': (
|
||||||
|
komp.get('komponenta_areal')
|
||||||
|
or {}
|
||||||
|
).get('value', ""),
|
||||||
|
'komponenta_obdobi': (
|
||||||
|
komp.get('komponenta_obdobi')
|
||||||
|
or {}
|
||||||
|
).get('value', ""),
|
||||||
|
}
|
||||||
|
pian_lookup[dj_pian_value].append(komp_meta)
|
||||||
|
target_pian_ids_count += 1
|
||||||
|
else:
|
||||||
|
# DJ without components — still include
|
||||||
|
# with empty component fields
|
||||||
|
if filter_areal or filter_datace:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
komp_meta = {
|
empty_meta = {
|
||||||
**dj_meta,
|
**dj_meta,
|
||||||
'komponenta_id': komp.get(
|
'komponenta_id': "",
|
||||||
'ident_cely',
|
'komponenta_areal': "",
|
||||||
""
|
'komponenta_obdobi': "",
|
||||||
),
|
|
||||||
'komponenta_areal': (
|
|
||||||
komp.get('komponenta_areal')
|
|
||||||
or {}
|
|
||||||
).get('value', ""),
|
|
||||||
'komponenta_obdobi': (
|
|
||||||
komp.get('komponenta_obdobi')
|
|
||||||
or {}
|
|
||||||
).get('value', ""),
|
|
||||||
}
|
}
|
||||||
pian_lookup[dj_pian_value].append(komp_meta)
|
pian_lookup[dj_pian_value].append(empty_meta)
|
||||||
target_pian_ids_count += 1
|
target_pian_ids_count += 1
|
||||||
else:
|
else:
|
||||||
# DJ without components — still include
|
|
||||||
# with empty component fields
|
|
||||||
if filter_areal or filter_datace:
|
|
||||||
continue
|
|
||||||
|
|
||||||
empty_meta = {
|
|
||||||
**dj_meta,
|
|
||||||
'komponenta_id': "",
|
|
||||||
'komponenta_areal': "",
|
|
||||||
'komponenta_obdobi': "",
|
|
||||||
}
|
|
||||||
pian_lookup[dj_pian_value].append(empty_meta)
|
|
||||||
target_pian_ids_count += 1
|
target_pian_ids_count += 1
|
||||||
else:
|
pian_lookup[dj_pian_value].append(dj_meta)
|
||||||
target_pian_ids_count += 1
|
|
||||||
pian_lookup[dj_pian_value].append(dj_meta)
|
if not target_pian_ids:
|
||||||
|
iface.messageBar().pushMessage(
|
||||||
|
"AMCR",
|
||||||
|
f"Nalezeno {len(docs)} záznamů, ale žádný nemá geometrii.",
|
||||||
|
level=Qgis.MessageLevel.Warning
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# C) GEOMETRY FETCHING (PIAN)
|
||||||
|
# ==========================================
|
||||||
|
ids_list = list(target_pian_ids)
|
||||||
|
total_pians = len(ids_list)
|
||||||
|
docs_pian = []
|
||||||
|
# Geometry requests are batch-processed
|
||||||
|
# to stay under URL length limits:
|
||||||
|
BATCH_PIAN = 200
|
||||||
|
|
||||||
if not target_pian_ids:
|
|
||||||
iface.messageBar().pushMessage(
|
iface.messageBar().pushMessage(
|
||||||
"AMCR",
|
"AMCR",
|
||||||
f"Nalezeno {len(docs)} záznamů, ale žádný nemá geometrii.",
|
f"Záznamů: {len(docs)} (z toho {actions_with_geom} s mapou). "
|
||||||
level=Qgis.MessageLevel.Warning
|
f"Stahuji {total_pians} unikátních geometrií, "
|
||||||
|
f"vykresluji {target_pian_ids_count} geometrií...",
|
||||||
|
level=Qgis.MessageLevel.Info
|
||||||
)
|
)
|
||||||
return
|
|
||||||
|
|
||||||
# ==========================================
|
fl_pian = [
|
||||||
# C) GEOMETRY FETCHING (PIAN)
|
"ident_cely",
|
||||||
# ==========================================
|
"pian_typ",
|
||||||
ids_list = list(target_pian_ids)
|
"pian_chranene_udaje",
|
||||||
total_pians = len(ids_list)
|
"pian_presnost",
|
||||||
docs_pian = []
|
]
|
||||||
# Geometry requests are batch-processed
|
|
||||||
# to stay under URL length limits:
|
|
||||||
BATCH_PIAN = 200
|
|
||||||
|
|
||||||
iface.messageBar().pushMessage(
|
for i in range(0, total_pians, BATCH_PIAN):
|
||||||
"AMCR",
|
batch = ids_list[i: i + BATCH_PIAN]
|
||||||
f"Záznamů: {len(docs)} (z toho {actions_with_geom} s mapou). "
|
or_query = " OR ".join(batch)
|
||||||
f"Stahuji {total_pians} unikátních geometrií, "
|
fq_pian = f"ident_cely:({or_query})"
|
||||||
f"vykresluji {target_pian_ids_count} geometrií...",
|
|
||||||
level=Qgis.MessageLevel.Info
|
|
||||||
)
|
|
||||||
|
|
||||||
fl_pian = [
|
params_pian = {
|
||||||
"ident_cely",
|
"mapa": "true",
|
||||||
"pian_typ",
|
"entity": "pian",
|
||||||
"pian_chranene_udaje",
|
"q": fq_pian,
|
||||||
"pian_presnost",
|
"rows": len(batch),
|
||||||
]
|
"fl": ",".join(fl_pian),
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
QApplication.processEvents()
|
||||||
|
r_json = _api_get_json(url, params=params_pian, timeout=15)
|
||||||
|
docs_pian.extend(r_json.get('response', {}).get('docs', []))
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
# Network is down – stop immediately instead of
|
||||||
|
# uselessly retrying every remaining batch
|
||||||
|
network_error = True
|
||||||
|
QgsMessageLog.logMessage(
|
||||||
|
f"Chyba sítě při stahování geometrií PIAN: {e}",
|
||||||
|
"AMČR", Qgis.MessageLevel.Critical
|
||||||
|
)
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
QgsMessageLog.logMessage(
|
||||||
|
f"Chyba PIAN: {e}",
|
||||||
|
"AMČR", Qgis.MessageLevel.Warning
|
||||||
|
)
|
||||||
|
|
||||||
for i in range(0, total_pians, BATCH_PIAN):
|
elif typ_dat == "samostatny_nalez":
|
||||||
batch = ids_list[i: i + BATCH_PIAN]
|
for doc in docs:
|
||||||
or_query = " OR ".join(batch)
|
loc = g(doc, "loc", [])
|
||||||
fq_pian = f"ident_cely:({or_query})"
|
if not loc:
|
||||||
|
continue
|
||||||
|
|
||||||
params_pian = {
|
actions_with_geom += 1
|
||||||
"mapa": "true",
|
|
||||||
"entity": "pian",
|
sn_chranene = doc.get("samostatny_nalez_chranene_udaje") or {}
|
||||||
"q": fq_pian,
|
|
||||||
"rows": len(batch),
|
|
||||||
"fl": ",".join(fl_pian),
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
QApplication.processEvents()
|
|
||||||
r_json = _api_get_json(url, params=params_pian, timeout=15)
|
|
||||||
docs_pian.extend(r_json.get('response', {}).get('docs', []))
|
|
||||||
except requests.exceptions.RequestException as e:
|
|
||||||
# Network is down – stop immediately instead of
|
|
||||||
# uselessly retrying every remaining batch
|
|
||||||
network_error = True
|
|
||||||
QgsMessageLog.logMessage(
|
|
||||||
f"Chyba sítě při stahování geometrií PIAN: {e}",
|
|
||||||
"AMČR", Qgis.MessageLevel.Critical
|
|
||||||
)
|
|
||||||
break
|
|
||||||
except Exception as e:
|
|
||||||
QgsMessageLog.logMessage(
|
|
||||||
f"Chyba PIAN: {e}",
|
|
||||||
"AMČR", Qgis.MessageLevel.Warning
|
|
||||||
)
|
|
||||||
|
|
||||||
# ==========================================
|
# ==========================================
|
||||||
# D) LAYER CREATION (QGIS Memory Layers)
|
# D) LAYER CREATION (QGIS Memory Layers)
|
||||||
|
|||||||
Reference in new issue
Block a user