mirror of
https://github.com/ARUP-CAS/aiscr-qgis-amcr-viewer.git
synced 2026-06-19 04:12:55 +02:00
Merge pull request #11 from ARUP-CAS/restructuring-amcr_tools
amcr_tools.py was restructured to better match the Digital archive API structure.
This commit is contained in:
+50
-110
@@ -17,7 +17,8 @@ TRANSLATIONS = {}
|
|||||||
# Download Digiarchive's vocabulary
|
# Download Digiarchive's vocabulary
|
||||||
def load_translations():
|
def load_translations():
|
||||||
global TRANSLATIONS
|
global TRANSLATIONS
|
||||||
if TRANSLATIONS: return
|
if TRANSLATIONS:
|
||||||
|
return
|
||||||
|
|
||||||
url = "https://digiarchiv.aiscr.cz/api/assets/i18n/cs.json"
|
url = "https://digiarchiv.aiscr.cz/api/assets/i18n/cs.json"
|
||||||
try:
|
try:
|
||||||
@@ -28,7 +29,8 @@ def load_translations():
|
|||||||
print(f"Chyba při stahování hesláře: {e}")
|
print(f"Chyba při stahování hesláře: {e}")
|
||||||
|
|
||||||
def tr_code(code):
|
def tr_code(code):
|
||||||
if not code: return ""
|
if not code:
|
||||||
|
return ""
|
||||||
return TRANSLATIONS.get(code, code)
|
return TRANSLATIONS.get(code, code)
|
||||||
|
|
||||||
def load_amcr_data(canvas, bb, filters=None):
|
def load_amcr_data(canvas, bb, filters=None):
|
||||||
@@ -54,7 +56,6 @@ def load_amcr_data(canvas, bb, filters=None):
|
|||||||
|
|
||||||
base_params = {
|
base_params = {
|
||||||
"mapa": "true",
|
"mapa": "true",
|
||||||
#"isExport": "true",
|
|
||||||
"entity": "akce",
|
"entity": "akce",
|
||||||
"sort": "ident_cely asc"
|
"sort": "ident_cely asc"
|
||||||
}
|
}
|
||||||
@@ -65,7 +66,8 @@ def load_amcr_data(canvas, bb, filters=None):
|
|||||||
# Apply filters
|
# Apply filters
|
||||||
if filters:
|
if filters:
|
||||||
for key, value in filters.items():
|
for key, value in filters.items():
|
||||||
if not value: continue
|
if not value:
|
||||||
|
continue
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
base_params[key] = [f"{v}:or" for v in value]
|
base_params[key] = [f"{v}:or" for v in value]
|
||||||
else:
|
else:
|
||||||
@@ -128,43 +130,24 @@ def load_amcr_data(canvas, bb, filters=None):
|
|||||||
pian_lookup = {}
|
pian_lookup = {}
|
||||||
target_pian_ids = set()
|
target_pian_ids = set()
|
||||||
actions_with_geom = 0
|
actions_with_geom = 0
|
||||||
negative_dj_pian_ids = set()
|
|
||||||
|
|
||||||
for akce in docs_akce:
|
for akce in docs_akce:
|
||||||
piani = akce.get('az_dj_pian', [])
|
piani = akce.get('az_dj_pian', [])
|
||||||
if not piani: continue
|
if not piani:
|
||||||
|
continue
|
||||||
negative_pians = set()
|
|
||||||
# Pokud je aktivní filtr 'posevidence', projdeme dokumentační jednotky
|
|
||||||
if filters and filters.get('posevidence') == 'true':
|
|
||||||
djs = akce.get('az_dokumentacni_jednotka', [])
|
|
||||||
for dj in djs:
|
|
||||||
# Pokud je jednotka negativní
|
|
||||||
if dj.get('dj_negativni_jednotka') is True:
|
|
||||||
# Získáme ID pianu z objektu (např. {"id": "P-...", "value": "..."})
|
|
||||||
pian_obj = dj.get('dj_pian')
|
|
||||||
if pian_obj and isinstance(pian_obj, dict):
|
|
||||||
negative_pians.add(pian_obj.get('id'))
|
|
||||||
|
|
||||||
djs = akce.get('az_dokumentacni_jednotka', [])
|
|
||||||
for dj in djs:
|
|
||||||
is_negative = dj.get('dj_negativni_jednotka')
|
|
||||||
if is_negative is True or str(is_negative).lower() == 'true':
|
|
||||||
# Získáme ID pianu z objektu (např. {"id": "P-...", "value": "..."})
|
|
||||||
pian_obj = dj.get('dj_pian')
|
|
||||||
if pian_obj and isinstance(pian_obj, dict):
|
|
||||||
negative_dj_pian_ids.add(pian_obj.get('id'))
|
|
||||||
|
|
||||||
actions_with_geom += 1
|
actions_with_geom += 1
|
||||||
|
|
||||||
def g(key, default=""):
|
def g(key, default=""):
|
||||||
val = akce.get(key)
|
val = akce.get(key)
|
||||||
if isinstance(val, list): return str(val[0]) if val else default
|
if isinstance(val, list):
|
||||||
|
return str(val[0]) if val else default
|
||||||
return str(val) if val is not None else default
|
return str(val) if val is not None else default
|
||||||
|
|
||||||
def g_list(key, translate=False):
|
def g_list(key, translate=False):
|
||||||
val = akce.get(key, [])
|
val = akce.get(key, [])
|
||||||
if not isinstance(val, list): val = [val] if val else []
|
if not isinstance(val, list):
|
||||||
|
val = [val] if val else []
|
||||||
if translate:
|
if translate:
|
||||||
return ", ".join([tr_code(str(x)) for x in val if x])
|
return ", ".join([tr_code(str(x)) for x in val if x])
|
||||||
return ", ".join([str(x) for x in val if x])
|
return ", ".join([str(x) for x in val if x])
|
||||||
@@ -199,16 +182,28 @@ def load_amcr_data(canvas, bb, filters=None):
|
|||||||
"loc": g_list('loc')
|
"loc": g_list('loc')
|
||||||
}
|
}
|
||||||
|
|
||||||
for pid in piani:
|
djs = akce.get('az_dokumentacni_jednotka', [])
|
||||||
if pid in negative_pians:
|
|
||||||
|
for dj in djs:
|
||||||
|
if filters and filters.get('posevidence') == 'true' and dj.get('dj_negativni_jednotka') is True:
|
||||||
continue
|
continue
|
||||||
pian_lookup[pid] = meta
|
dj_meta = meta.copy()
|
||||||
target_pian_ids.add(pid)
|
dj_meta['dj_id'] = dj.get('ident_cely')
|
||||||
|
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í"
|
||||||
|
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)
|
||||||
|
pian_lookup[dj_pian_value] = dj_meta
|
||||||
|
|
||||||
if not target_pian_ids:
|
if not target_pian_ids:
|
||||||
iface.messageBar().pushMessage("AMCR", f"Nalezeno {len(docs_akce)} akcí, ale žádná nemá geometrii.", level=1)
|
iface.messageBar().pushMessage("AMCR", f"Nalezeno {len(docs_akce)} akcí, ale žádná nemá geometrii.", level=1)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# ==========================================
|
# ==========================================
|
||||||
# B) Geometry (PIAN)
|
# B) Geometry (PIAN)
|
||||||
# ==========================================
|
# ==========================================
|
||||||
@@ -255,9 +250,11 @@ def load_amcr_data(canvas, bb, filters=None):
|
|||||||
QgsField("PIAN", QVariant.String),
|
QgsField("PIAN", QVariant.String),
|
||||||
QgsField("Přesnost", QVariant.String),
|
QgsField("Přesnost", QVariant.String),
|
||||||
QgsField("PIAN – typ", QVariant.String),
|
QgsField("PIAN – typ", QVariant.String),
|
||||||
|
QgsField("Dokumentační jednotka", QVariant.String),
|
||||||
|
QgsField("Typ dokumentační jednotky", QVariant.String),
|
||||||
QgsField("Definiční bod(y) (WGS-84)", QVariant.String),
|
QgsField("Definiční bod(y) (WGS-84)", QVariant.String),
|
||||||
QgsField("Identifikátor", QVariant.String),
|
QgsField("Akce", QVariant.String),
|
||||||
QgsField("Odkaz do Digiarchivu", QVariant.String),
|
QgsField("Odkaz do Digitálního archivu AMČR", QVariant.String),
|
||||||
QgsField("Okres", QVariant.String),
|
QgsField("Okres", QVariant.String),
|
||||||
QgsField("Katastr", QVariant.String),
|
QgsField("Katastr", QVariant.String),
|
||||||
QgsField("Další katastry", QVariant.String),
|
QgsField("Další katastry", QVariant.String),
|
||||||
@@ -270,7 +267,7 @@ def load_amcr_data(canvas, bb, filters=None):
|
|||||||
QgsField("Vedlejší typ", QVariant.String),
|
QgsField("Vedlejší typ", QVariant.String),
|
||||||
QgsField("Zjištění", QVariant.String),
|
QgsField("Zjištění", QVariant.String),
|
||||||
QgsField("Akce – lokalizace", QVariant.String),
|
QgsField("Akce – lokalizace", QVariant.String),
|
||||||
QgsField("Akce - nahrazuje NZ", QVariant.String),
|
QgsField("Akce – nahrazuje NZ", QVariant.String),
|
||||||
QgsField("Přístupnost", QVariant.String)
|
QgsField("Přístupnost", QVariant.String)
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -283,23 +280,26 @@ def load_amcr_data(canvas, bb, filters=None):
|
|||||||
for doc in docs_pian:
|
for doc in docs_pian:
|
||||||
try:
|
try:
|
||||||
pid = doc.get('ident_cely', '')
|
pid = doc.get('ident_cely', '')
|
||||||
if pid not in pian_lookup: continue
|
if pid not in pian_lookup:
|
||||||
|
continue
|
||||||
|
|
||||||
meta = pian_lookup[pid]
|
meta = pian_lookup[pid]
|
||||||
|
|
||||||
# Geometry processing
|
# Geometry processing
|
||||||
raw = doc.get('pian_chranene_udaje')
|
raw = doc.get('pian_chranene_udaje')
|
||||||
if isinstance(raw, list) and raw: raw = raw[0]
|
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 if isinstance(raw, dict) else {})
|
||||||
|
|
||||||
wkt = None
|
wkt = None
|
||||||
if jdata.get('geom_sjtsk_wkt'): wkt = jdata['geom_sjtsk_wkt'].get('value')
|
if jdata.get('geom_sjtsk_wkt'):
|
||||||
elif jdata.get('geom_wkt'): wkt = jdata['geom_wkt'].get('value')
|
wkt = jdata['geom_sjtsk_wkt'].get('value')
|
||||||
|
elif jdata.get('geom_wkt'):
|
||||||
|
wkt = jdata['geom_wkt'].get('value')
|
||||||
|
|
||||||
# PIAN attributes
|
# PIAN attributes
|
||||||
pian_presnost = tr_code(str(doc.get('pian_presnost', '')))
|
pian_presnost = tr_code(str(doc.get('pian_presnost', '')))
|
||||||
pian_typ = tr_code(str(doc.get('pian_typ', '')))
|
pian_typ = tr_code(str(doc.get('pian_typ', '')))
|
||||||
dj_negativni = "Negativní" if pid in negative_dj_pian_ids else "Pozitivní"
|
|
||||||
|
|
||||||
if wkt:
|
if wkt:
|
||||||
geom = QgsGeometry.fromWkt(wkt)
|
geom = QgsGeometry.fromWkt(wkt)
|
||||||
@@ -310,6 +310,8 @@ def load_amcr_data(canvas, bb, filters=None):
|
|||||||
pid,
|
pid,
|
||||||
pian_presnost,
|
pian_presnost,
|
||||||
pian_typ,
|
pian_typ,
|
||||||
|
meta['dj_id'],
|
||||||
|
meta['dj_typ_value'],
|
||||||
meta['loc'],
|
meta['loc'],
|
||||||
meta['ident_cely'],
|
meta['ident_cely'],
|
||||||
"https://digiarchiv.aiscr.cz/id/" + meta['ident_cely'],
|
"https://digiarchiv.aiscr.cz/id/" + meta['ident_cely'],
|
||||||
@@ -323,15 +325,18 @@ def load_amcr_data(canvas, bb, filters=None):
|
|||||||
meta['akce_datum_ukonceni'],
|
meta['akce_datum_ukonceni'],
|
||||||
meta['akce_hlavni_typ'],
|
meta['akce_hlavni_typ'],
|
||||||
meta['akce_vedlejsi_typ'],
|
meta['akce_vedlejsi_typ'],
|
||||||
dj_negativni,
|
meta['dj_negativni'],
|
||||||
meta['lokalizace_okolnosti'],
|
meta['lokalizace_okolnosti'],
|
||||||
meta['akce_je_nz'],
|
meta['akce_je_nz'],
|
||||||
meta['pristupnost']
|
meta['pristupnost']
|
||||||
])
|
])
|
||||||
t = geom.type()
|
t = geom.type()
|
||||||
if t == QgsWkbTypes.PolygonGeometry: feats_p.append(feat)
|
if t == QgsWkbTypes.PolygonGeometry:
|
||||||
elif t == QgsWkbTypes.LineGeometry: feats_l.append(feat)
|
feats_p.append(feat)
|
||||||
elif t == QgsWkbTypes.PointGeometry: feats_pt.append(feat)
|
elif t == QgsWkbTypes.LineGeometry:
|
||||||
|
feats_l.append(feat)
|
||||||
|
elif t == QgsWkbTypes.PointGeometry:
|
||||||
|
feats_pt.append(feat)
|
||||||
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
|
||||||
@@ -355,68 +360,3 @@ def load_amcr_data(canvas, bb, filters=None):
|
|||||||
iface.messageBar().pushMessage("Chyba", str(e), level=2)
|
iface.messageBar().pushMessage("Chyba", str(e), level=2)
|
||||||
finally:
|
finally:
|
||||||
QApplication.restoreOverrideCursor()
|
QApplication.restoreOverrideCursor()
|
||||||
|
|
||||||
# class AmcrIdentifyTool(QgsMapToolIdentifyFeature):
|
|
||||||
# def __init__(self, canvas):
|
|
||||||
# super().__init__(canvas)
|
|
||||||
# self.canvas = canvas
|
|
||||||
# self.setCursor(Qt.CrossCursor)
|
|
||||||
|
|
||||||
# def canvasReleaseEvent(self, event):
|
|
||||||
# results = self.identify(event.x(), event.y(), self.IdentifyMode.TopDownStopAtFirst, self.VectorLayer)
|
|
||||||
# if not results: return
|
|
||||||
# feature = results[0].mFeature
|
|
||||||
# akce_id = None
|
|
||||||
# # Změna: hledáme 'ident_cely' (ID akce)
|
|
||||||
# idx = feature.fieldNameIndex('ident_cely')
|
|
||||||
# if idx != -1:
|
|
||||||
# akce_id = feature.attributes()[idx]
|
|
||||||
|
|
||||||
# # Fallback na starší názvy polí, kdyby něco
|
|
||||||
# if not akce_id:
|
|
||||||
# for col in ['akce_id', 'ident_cely', 'pian_id']:
|
|
||||||
# if col in feature.fields().names():
|
|
||||||
# akce_id = feature[col]
|
|
||||||
# break
|
|
||||||
|
|
||||||
# if not akce_id: return
|
|
||||||
|
|
||||||
# full_id = akce_id if "api.aiscr.cz" in str(akce_id) else f"https://api.aiscr.cz/id/{akce_id}"
|
|
||||||
# url = f"https://api.aiscr.cz/2.2/oai?verb=GetRecord&metadataPrefix=oai_amcr&identifier={full_id}"
|
|
||||||
|
|
||||||
# iface.messageBar().pushMessage("AMCR", f"Detail: {akce_id}...", level=1)
|
|
||||||
# QApplication.setOverrideCursor(Qt.WaitCursor)
|
|
||||||
# try:
|
|
||||||
# r = requests.get(url, timeout=5)
|
|
||||||
# if r.status_code == 200: self.show_detail(akce_id, r.text)
|
|
||||||
# except Exception as e:
|
|
||||||
# iface.messageBar().pushMessage("Chyba", str(e), level=2)
|
|
||||||
# finally:
|
|
||||||
# QApplication.restoreOverrideCursor()
|
|
||||||
|
|
||||||
# def show_detail(self, title, raw_xml):
|
|
||||||
# xml = re.sub(r'\sxmlns="[^"]+"', '', raw_xml, count=1)
|
|
||||||
# xml = re.sub(r'<(/?)[a-zA-Z0-9]+:', r'<\1', xml)
|
|
||||||
# info = ""
|
|
||||||
# try:
|
|
||||||
# root = ET.fromstring(xml)
|
|
||||||
# rec = root.find('.//archeologicky_zaznam')
|
|
||||||
# if not rec: info = "Zadna data."
|
|
||||||
# else:
|
|
||||||
# kat = rec.find('.//hlavni_katastr')
|
|
||||||
# info += f"<h3>{kat.text if kat is not None else '?'}</h3>"
|
|
||||||
# for dj in rec.findall('.//dokumentacni_jednotka'):
|
|
||||||
# pn = dj.find('pian')
|
|
||||||
# p_txt = pn.text if pn is not None else ""
|
|
||||||
# info += f"<hr><b>PIAN: {p_txt}</b><ul>"
|
|
||||||
# for k in dj.findall('komponenta'):
|
|
||||||
# ob = k.find('obdobi').text or "?"
|
|
||||||
# ar = k.find('areal').text or "?"
|
|
||||||
# info += f"<li>{ob} ({ar})</li>"
|
|
||||||
# info += "</ul>"
|
|
||||||
# dlg = QMessageBox()
|
|
||||||
# dlg.setWindowTitle(str(title))
|
|
||||||
# dlg.setText(info)
|
|
||||||
# dlg.setTextFormat(Qt.RichText)
|
|
||||||
# dlg.exec_()
|
|
||||||
# except: pass
|
|
||||||
@@ -3,7 +3,7 @@ from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
|
|||||||
from qgis.PyQt.QtGui import QIcon
|
from qgis.PyQt.QtGui import QIcon
|
||||||
from qgis.PyQt.QtWidgets import QAction
|
from qgis.PyQt.QtWidgets import QAction
|
||||||
|
|
||||||
from .amcr_tools import load_amcr_data#, AmcrIdentifyTool
|
from .amcr_tools import load_amcr_data
|
||||||
from .amcr_dialog import AmcrFilterDialog
|
from .amcr_dialog import AmcrFilterDialog
|
||||||
from .resources import *
|
from .resources import *
|
||||||
import os.path
|
import os.path
|
||||||
@@ -61,7 +61,6 @@ class AmcrViewer:
|
|||||||
|
|
||||||
icon = QIcon(os.path.join(plugin_dir, 'download.png'))
|
icon = QIcon(os.path.join(plugin_dir, 'download.png'))
|
||||||
|
|
||||||
# icon_info = QIcon(os.path.join(plugin_dir, 'info.png'))
|
|
||||||
|
|
||||||
# Download data button
|
# Download data button
|
||||||
self.action_download = self.add_action(
|
self.action_download = self.add_action(
|
||||||
@@ -70,14 +69,6 @@ class AmcrViewer:
|
|||||||
callback=self.run_download,
|
callback=self.run_download,
|
||||||
parent=self.iface.mainWindow())
|
parent=self.iface.mainWindow())
|
||||||
|
|
||||||
# # Info button (Checkable / Toggle)
|
|
||||||
# self.action_tool = self.add_action(
|
|
||||||
# icon_info,
|
|
||||||
# text=self.tr(u'Výpis údajů záznamu'),
|
|
||||||
# callback=self.run_tool,
|
|
||||||
# parent=self.iface.mainWindow())
|
|
||||||
# self.action_tool.setCheckable(True) # Toto tlačítko se zamačkává
|
|
||||||
|
|
||||||
self.first_start = True
|
self.first_start = True
|
||||||
|
|
||||||
def unload(self):
|
def unload(self):
|
||||||
@@ -100,20 +91,3 @@ class AmcrViewer:
|
|||||||
|
|
||||||
canvas = self.iface.mapCanvas()
|
canvas = self.iface.mapCanvas()
|
||||||
load_amcr_data(canvas, bbox, filters)
|
load_amcr_data(canvas, bbox, filters)
|
||||||
|
|
||||||
# --- Info button toggle ---
|
|
||||||
# def run_tool(self):
|
|
||||||
|
|
||||||
# if self.action_tool.isChecked():
|
|
||||||
# canvas = self.iface.mapCanvas()
|
|
||||||
|
|
||||||
# if not hasattr(self, 'tool'):
|
|
||||||
# self.tool = AmcrIdentifyTool(canvas)
|
|
||||||
# self.tool.deactivated.connect(lambda: self.action_tool.setChecked(False))
|
|
||||||
|
|
||||||
# canvas.setMapTool(self.tool)
|
|
||||||
# self.iface.messageBar().pushMessage("AMČR", "Info nástroj aktivní.", level=0)
|
|
||||||
|
|
||||||
# else:
|
|
||||||
# if self.iface.mapCanvas().mapTool() == getattr(self, 'tool', None):
|
|
||||||
# self.iface.mapCanvas().unsetMapTool(self.tool)
|
|
||||||
Reference in New Issue
Block a user