kód pro filtrování a stahování lokalit + doprovodné změny

This commit is contained in:
2026-03-09 16:49:30 +01:00
parent 9559712af9
commit 78bad9aaa7
10 changed files with 257 additions and 49 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

+7 -2
View File
@@ -62,7 +62,8 @@ def load_all_data():
categorized_data = {
'obdobi': {}, 'typ_akce': {}, 'areal': {},
'kraj': {}, 'organizace': {}, 'okres': {}, 'katastr': {},
'vedouci': {}, 'pian_presnost': {}
'vedouci': {}, 'pian_presnost': {}, 'typ_lokality': {}, 'druh_lokality': {},
'jistota': {}, 'lokalita_zachovalost': {}
}
# Funkce pro roztřídění načteného slovníku (tohle je trochu redundance, ale pro zachování logiky)
@@ -156,8 +157,12 @@ KRAJE = _DATA['kraj']
ORGANIZACE = _DATA['organizace']
OKRESY = _DATA['okres']
KATASTRY = _DATA['katastr']
VEDOUCI = _DATA['vedouci'] # Tady to bude zpočátku prázdné, pokud soubor neexistuje
VEDOUCI = _DATA['vedouci']
PIAN_PRESNOST = _DATA['pian_presnost']
TYP_LOKALITY = _DATA['typ_lokality']
DRUH_LOKALITY = _DATA['druh_lokality']
JISTOTA = _DATA['jistota']
LOKALITA_ZACHOVALOST = _DATA['lokalita_zachovalost']
def refresh_vedouci_cache():
"""
+76 -31
View File
@@ -6,7 +6,8 @@ from qgis.PyQt.QtWidgets import (QDialog, QVBoxLayout, QFormLayout,
QLabel, QMessageBox, QApplication, QWidget)
from qgis.PyQt.QtCore import Qt
from .amcr_codelists import (OBDOBI, TYP_AKCE, KRAJE, AREAL, ORGANIZACE,
OKRESY, KATASTRY, VEDOUCI, PIAN_PRESNOST,
OKRESY, KATASTRY, VEDOUCI, PIAN_PRESNOST, TYP_LOKALITY,
DRUH_LOKALITY, JISTOTA, LOKALITA_ZACHOVALOST,
download_vedouci, refresh_vedouci_cache)
class FilterableSelectionDialog(QDialog):
@@ -65,15 +66,19 @@ class FilterableSelectionDialog(QDialog):
# --- Main window ---
class AmcrFilterDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
def __init__(self, typ_dat, parent=None):
super(AmcrFilterDialog, self).__init__(parent)
self.setWindowTitle("Filtr AMČR")
self.resize(500, 750)
self.typ_dat = typ_dat
# Cache for filtering
self.selection_cache = {
'organizace': [], 'kraj': [], 'obdobi': [], 'areal': [],
'typ_akce': [], 'okres': [], 'katastr': [], 'vedouci': [], 'pian_presnost': []
'typ_akce': [], 'okres': [], 'katastr': [], 'vedouci': [], 'pian_presnost': [],
'typ_lokality': [], 'druh_lokality': [], 'jistota': [], 'lokalita_zachovalost': []
}
layout = QVBoxLayout()
@@ -82,8 +87,11 @@ class AmcrFilterDialog(QDialog):
self.chk_bbox.setChecked(True)
layout.addWidget(self.chk_bbox)
self.chk_posevidence = QCheckBox("Pouze pozitivní zjištění")
layout.addWidget(self.chk_posevidence)
# Positive/negative evidence valid for Akce
if self.typ_dat == "akce":
self.chk_posevidence = QCheckBox("Pouze pozitivní zjištění")
layout.addWidget(self.chk_posevidence)
layout.addSpacing(10)
@@ -127,6 +135,8 @@ class AmcrFilterDialog(QDialog):
row_widget.setLayout(row_layout)
return row_widget
# Spatial information valid for all
self.picker_kraj = setup_picker("Kraj", 'kraj', KRAJE)
layout.addWidget(self.picker_kraj)
@@ -136,28 +146,52 @@ class AmcrFilterDialog(QDialog):
self.picker_katastr = setup_picker("Katastr", 'katastr', KATASTRY)
layout.addWidget(self.picker_katastr)
self.picker_org = setup_picker("Organizace", 'organizace', ORGANIZACE)
layout.addWidget(self.picker_org)
self.picker_presnost = setup_picker("PIAN přesnost", 'pian_presnost', PIAN_PRESNOST)
layout.addWidget(self.picker_presnost)
self.btn_update_vedouci = QPushButton("🔄")
self.btn_update_vedouci.setToolTip("Aktualizovat seznam vedoucích z API")
self.btn_update_vedouci.setFixedWidth(30)
self.btn_update_vedouci.clicked.connect(self.action_update_vedouci)
# Filters valid for Akce
if self.typ_dat == "akce":
self.picker_org = setup_picker("Organizace", 'organizace', ORGANIZACE)
layout.addWidget(self.picker_org)
self.btn_update_vedouci = QPushButton("🔄")
self.btn_update_vedouci.setToolTip("Aktualizovat seznam vedoucích z API")
self.btn_update_vedouci.setFixedWidth(30)
self.btn_update_vedouci.clicked.connect(self.action_update_vedouci)
self.picker_vedouci = setup_picker("Vedoucí výzkumu", 'vedouci', VEDOUCI, extra_btn=self.btn_update_vedouci)
layout.addWidget(self.picker_vedouci)
self.picker_vedouci = setup_picker("Vedoucí výzkumu", 'vedouci', VEDOUCI, extra_btn=self.btn_update_vedouci)
layout.addWidget(self.picker_vedouci)
# Type of event
self.picker_typ = setup_picker("Typ výzkumu", 'typ_akce', TYP_AKCE)
layout.addWidget(self.picker_typ)
# Filters valid for Lokality
if self.typ_dat == "lokalita":
self.picker_typ_lokality = setup_picker("Lokalita typ", 'typ_lokality', TYP_LOKALITY)
layout.addWidget(self.picker_typ_lokality)
self.picker_druh_lokality = setup_picker("Lokalita druh", 'druh_lokality', DRUH_LOKALITY)
layout.addWidget(self.picker_druh_lokality)
self.picker_jistota = setup_picker("Lokalita jistota určení", 'jistota', JISTOTA)
layout.addWidget(self.picker_jistota)
self.picker_lokalita_zachovalost = setup_picker("Lokalita - stav dochování", 'lokalita_zachovalost', LOKALITA_ZACHOVALOST)
layout.addWidget(self.picker_lokalita_zachovalost)
# Contextual information
self.picker_obdobi = setup_picker("Období", 'obdobi', OBDOBI)
layout.addWidget(self.picker_obdobi)
self.picker_areal = setup_picker("Areál / Druh", 'areal', AREAL)
self.picker_areal = setup_picker("Areál", 'areal', AREAL)
layout.addWidget(self.picker_areal)
self.picker_typ = setup_picker("Typ výzkumu", 'typ_akce', TYP_AKCE)
layout.addWidget(self.picker_typ)
self.picker_presnost = setup_picker("PIAN přesnost", 'pian_presnost', PIAN_PRESNOST)
layout.addWidget(self.picker_presnost)
layout.addStretch(1)
@@ -188,12 +222,7 @@ class AmcrFilterDialog(QDialog):
def get_filters(self):
filters = {}
if self.chk_posevidence.isChecked():
filters['posevidence'] = 'true'
# Loading from cache
if self.selection_cache['organizace']:
filters['f_organizace'] = self.selection_cache['organizace']
if self.selection_cache['kraj']:
filters['f_kraj'] = self.selection_cache['kraj']
if self.selection_cache['okres']:
@@ -204,11 +233,27 @@ class AmcrFilterDialog(QDialog):
filters['f_obdobi'] = self.selection_cache['obdobi']
if self.selection_cache['areal']:
filters['f_areal'] = self.selection_cache['areal']
if self.selection_cache['typ_akce']:
filters['f_typ_vyzkumu'] = self.selection_cache['typ_akce']
if self.selection_cache['vedouci']:
filters['f_vedouci'] = self.selection_cache['vedouci']
if self.selection_cache['pian_presnost']:
filters['f_pian_presnost'] = self.selection_cache['pian_presnost']
filters['f_pian_presnost'] = self.selection_cache['pian_presnost']
if self.typ_dat == "akce":
if self.chk_posevidence.isChecked():
filters['posevidence'] = 'true'
if self.selection_cache['organizace']:
filters['f_organizace'] = self.selection_cache['organizace']
if self.selection_cache['typ_akce']:
filters['f_typ_vyzkumu'] = self.selection_cache['typ_akce']
if self.selection_cache['vedouci']:
filters['f_vedouci'] = self.selection_cache['vedouci']
if self.typ_dat == "lokalita":
if self.selection_cache['typ_lokality']:
filters['f_typ_lokality'] = self.selection_cache['typ_lokality']
if self.selection_cache['druh_lokality']:
filters['f_druh_lokality'] = self.selection_cache['druh_lokality']
if self.selection_cache['jistota']:
filters['f_jistota'] = self.selection_cache['jistota']
if self.selection_cache['lokalita_zachovalost']:
filters['f_lokalita_zachovalost'] = self.selection_cache['lokalita_zachovalost']
return filters
+4 -3
View File
@@ -33,7 +33,7 @@ def tr_code(code):
return ""
return TRANSLATIONS.get(code, code)
def load_amcr_data(canvas, bb, filters=None):
def load_amcr_data(canvas, bb, filters=None, typ_dat="akce"):
load_translations()
# 1. Bounding box
@@ -51,15 +51,16 @@ def load_amcr_data(canvas, bb, filters=None):
try:
# ===================
# A) METADATA (Fieldwork event)
# A) METADATA (Fieldwork event/Site)
# ===================
base_params = {
"mapa": "true",
"entity": "akce",
"sort": "ident_cely asc"
}
base_params["entity"] = typ_dat
if bb == "true":
base_params["loc_rpt"] = bbox_str
+43 -12
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction
from qgis.PyQt.QtWidgets import QMenu, QAction, QToolButton
from .amcr_tools import load_amcr_data
from .amcr_dialog import AmcrFilterDialog
@@ -58,16 +58,47 @@ class AmcrViewer:
import os
plugin_dir = os.path.dirname(__file__)
icon_akce_path = os.path.join(plugin_dir, 'akce.png')
icon_lokality_path = os.path.join(plugin_dir, 'lokality.png')
icon = QIcon(os.path.join(plugin_dir, 'download.png'))
# 1. Vytvoření společného menu
self.plugin_menu = QMenu()
# 2. Vytvoření akcí (bez automatického přidání do lišty a menu)
self.action_download_akce = self.add_action(
icon_path=icon_akce_path,
text=self.tr(u'Stáhnout data akcí | AMČR Viewer'),
callback=lambda checked=False: self.run_download('akce'),
parent=self.iface.mainWindow(),
add_to_menu=False,
add_to_toolbar=False
)
self.plugin_menu.addAction(self.action_download_akce)
self.action_download_lokality = self.add_action(
icon_path=icon_lokality_path,
text=self.tr(u'Stáhnout data lokalit | AMČR Viewer'),
callback=lambda checked=False: self.run_download('lokalita'),
parent=self.iface.mainWindow(),
add_to_menu=False,
add_to_toolbar=False
)
self.plugin_menu.addAction(self.action_download_lokality)
# 3. Přidání rozbalovacího menu do hlavního menu QGIS
main_icon = QIcon(icon_akce_path)
self.main_action = QAction(main_icon, 'AMČR Viewer', self.iface.mainWindow())
self.main_action.setMenu(self.plugin_menu)
self.iface.addPluginToMenu(self.menu, self.main_action)
# 4. Přidání rozevíracího tlačítka do nástrojové lišty (Toolbar)
self.tool_button = QToolButton()
self.tool_button.setMenu(self.plugin_menu)
self.tool_button.setDefaultAction(self.action_download_akce)
self.tool_button.setPopupMode(QToolButton.MenuButtonPopup)
# Download data button
self.action_download = self.add_action(
icon,
text=self.tr(u'Načíst data z AMČR'),
callback=self.run_download,
parent=self.iface.mainWindow())
# Vložení vytvořeného tlačítka do QGIS rozhraní
self.iface.addToolBarWidget(self.tool_button)
self.first_start = True
@@ -80,9 +111,9 @@ class AmcrViewer:
self.iface.mapCanvas().unsetMapTool(self.tool)
# --- Data downloading ---
def run_download(self):
def run_download(self, typ_dat):
dlg = AmcrFilterDialog()
dlg = AmcrFilterDialog(typ_dat)
result = dlg.exec_()
if result == 1:
@@ -90,4 +121,4 @@ class AmcrViewer:
bbox = dlg.get_bbox()
canvas = self.iface.mapCanvas()
load_amcr_data(canvas, bbox, filters)
load_amcr_data(canvas, bbox, filters, typ_dat)
+28 -1
View File
@@ -13617,4 +13617,31 @@ Zvotoky;Zvotoky;katastr
odchylka jednotky metrů;HES-000861;pian_presnost
odchylka desítky metrů;HES-000862;pian_presnost
odchylka stovky metrů;HES-000863;pian_presnost
poloha podle katastru;HES-000864;pian_presnost
poloha podle katastru;HES-000864;pian_presnost
nemovitá památka;HES-001122;typ_lokality
polygon průzkumu;HES-001123;typ_lokality
krajina;HES-001124;typ_lokality
polygon leteckého průzkumu;HES-000111;druh_lokality
osídlený skalní prostor;HES-000112;druh_lokality
krajina;HES-000117;druh_lokality
pomník/památník;HES-000128;druh_lokality
muzeum/skanzen;HES-000129;druh_lokality
pozůstatek mohylníku;HES-001430;druh_lokality
pozůstatek ohrazení;HES-001431;druh_lokality
pozůstatek represe;HES-001432;druh_lokality
pozůstatek kultu;HES-001433;druh_lokality
pozůstatek sídla elity;HES-001434;druh_lokality
pozůstatek sídliště;HES-001435;druh_lokality
pozůstatek těžby;HES-001436;druh_lokality
pozůstatek vojenství;HES-001437;druh_lokality
pozůstatek výroby;HES-001438;druh_lokality
pozůstatek komunikace;HES-001429;druh_lokality
jisté (> 95 %);HES-001449;jistota
nejisté (5095 %);HES-001450;jistota
domnělé (550 %);HES-001451;jistota
pseudolokalita (< 5 %);HES-001452;jistota
zaniklá lokalita;HES-001453;lokalita_zachovalost
lokalita pod zástavbou;HES-001454;lokalita_zachovalost
nadzemní relikty;HES-001455;lokalita_zachovalost
ruina;HES-001456;lokalita_zachovalost
historická budova/komplex;HES-001457;lokalita_zachovalost
1 Název Kód Kategorie
13617 odchylka jednotky metrů HES-000861 pian_presnost
13618 odchylka desítky metrů HES-000862 pian_presnost
13619 odchylka stovky metrů HES-000863 pian_presnost
13620 poloha podle katastru HES-000864 pian_presnost
13621 nemovitá památka HES-001122 typ_lokality
13622 polygon průzkumu HES-001123 typ_lokality
13623 krajina HES-001124 typ_lokality
13624 polygon leteckého průzkumu HES-000111 druh_lokality
13625 osídlený skalní prostor HES-000112 druh_lokality
13626 krajina HES-000117 druh_lokality
13627 pomník/památník HES-000128 druh_lokality
13628 muzeum/skanzen HES-000129 druh_lokality
13629 pozůstatek mohylníku HES-001430 druh_lokality
13630 pozůstatek ohrazení HES-001431 druh_lokality
13631 pozůstatek represe HES-001432 druh_lokality
13632 pozůstatek kultu HES-001433 druh_lokality
13633 pozůstatek sídla elity HES-001434 druh_lokality
13634 pozůstatek sídliště HES-001435 druh_lokality
13635 pozůstatek těžby HES-001436 druh_lokality
13636 pozůstatek vojenství HES-001437 druh_lokality
13637 pozůstatek výroby HES-001438 druh_lokality
13638 pozůstatek komunikace HES-001429 druh_lokality
13639 jisté (> 95 %) HES-001449 jistota
13640 nejisté (50–95 %) HES-001450 jistota
13641 domnělé (5–50 %) HES-001451 jistota
13642 pseudolokalita (< 5 %) HES-001452 jistota
13643 zaniklá lokalita HES-001453 lokalita_zachovalost
13644 lokalita pod zástavbou HES-001454 lokalita_zachovalost
13645 nadzemní relikty HES-001455 lokalita_zachovalost
13646 ruina HES-001456 lokalita_zachovalost
13647 historická budova/komplex HES-001457 lokalita_zachovalost
Binary file not shown.

Before

Width:  |  Height:  |  Size: 993 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B