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():
"""
+73 -28
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
self.picker_vedouci = setup_picker("Vedoucí výzkumu", 'vedouci', VEDOUCI, extra_btn=self.btn_update_vedouci)
layout.addWidget(self.picker_vedouci)
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)
# 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']
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
+42 -11
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)
# 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())
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)
# 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)
+27
View File
@@ -13618,3 +13618,30 @@ 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
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
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

+99
View File
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="24"
height="24"
viewBox="0 0 6.3499998 6.35"
version="1.1"
id="svg1"
xml:space="preserve"
sodipodi:docname="icon.svg"
inkscape:version="1.4.3 (0d15f75, 2025-12-25)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="22.627417"
inkscape:cx="6.8059028"
inkscape:cy="14.606174"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" /><defs
id="defs1"><clipPath
id="clip-0"><path
clip-rule="nonzero"
d="M 56 202 L 64 202 L 64 212.582031 L 56 212.582031 Z M 56 202 "
id="path1" /></clipPath><clipPath
id="clip-1"><path
clip-rule="nonzero"
d="M 111 202 L 120 202 L 120 212.582031 L 111 212.582031 Z M 111 202 "
id="path2" /></clipPath><clipPath
id="clip-2"><path
clip-rule="nonzero"
d="M 183 202 L 191 202 L 191 212.582031 L 183 212.582031 Z M 183 202 "
id="path3" /></clipPath><clipPath
id="clip-3"><path
clip-rule="nonzero"
d="M 220 202 L 227.445312 202 L 227.445312 212.582031 L 220 212.582031 Z M 220 202 "
id="path4" /></clipPath></defs><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"><path
id="path39"
style="display:inline"
d="M 81.817206 0.011405799 C 62.571113 1.6910933 45.354524 13.210298 36.479524 30.538423 C 32.381867 38.534516 30.312854 47.189295 30.312854 56.243982 C 30.312854 69.122889 34.534136 81.246352 42.526324 91.312758 L 43.405375 92.378274 C 46.932719 96.698587 50.2156 100.55118 53.367944 104.05899 C 53.414814 104.10979 53.454254 104.16803 53.501133 104.21881 L 66.540378 73.385461 C 62.46616 68.596398 60.240518 62.587732 60.240518 56.243982 C 60.240518 52.493982 61.017351 48.846969 62.544695 45.429001 C 66.806414 35.882126 76.317127 29.725967 86.758533 29.725967 C 89.688221 29.725967 92.538869 30.194768 95.269338 31.124456 L 99.957606 21.201844 L 84.214615 14.209399 L 81.817206 0.011405799 z M 90.381286 0.35769831 L 92.152705 10.813068 L 110.39966 18.924304 L 103.31398 34.107899 C 107.88529 36.880579 111.46702 40.963271 113.6628 45.722017 C 116.28908 45.714971 119.29963 45.708698 122.71968 45.708698 C 133.11322 45.708698 139.70768 45.745211 143.25749 45.81525 C 143.26209 45.815341 143.27953 45.815159 143.28413 45.81525 L 144.8824 45.349087 C 144.8707 45.298307 144.85424 45.240042 144.84244 45.18926 C 139.4715 19.302542 117.04145 0.71707431 90.381286 0.35769831 z M 70.962267 79.791873 L 57.590049 110.8916 C 62.425987 115.99706 66.178471 119.43931 69.510502 122.50572 C 75.319096 127.84947 80.037477 132.17422 86.771852 142.01797 C 92.93488 133.01459 97.405493 128.62293 102.56812 123.85094 C 91.347418 109.36236 78.096901 91.972441 77.661695 90.939828 C 76.892417 89.114561 76.908479 86.67687 77.701652 84.946304 C 77.897699 84.518565 78.148245 84.087284 78.434194 83.681004 C 75.760133 82.798967 73.242325 81.491624 70.962267 79.791873 z "
transform="matrix(0.0387992,0,0,0.0387992,-0.55393024,0.41865333)" /><path
id="rect30"
style="display:none;opacity:1;fill:#00b200;stroke:#ffffff;stroke-width:0.615;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;paint-order:stroke fill markers"
d="m 3.3486328,2.4970052 v 1.335319 H 2.7424683 L 4.2085286,5.738151 5.674589,3.8323242 H 5.0684245 v -1.335319 z" /><rect
style="opacity:1;fill:#247e4b;fill-opacity:1;stroke:none;stroke-width:0.414999;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;paint-order:stroke fill markers"
id="rect31"
width="1.672105"
height="1.2511554"
x="-4.501821"
y="0.84189904" /><text
xml:space="preserve"
style="font-size:0.705556px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;opacity:1;fill:#247e4b;fill-opacity:1;stroke:none;stroke-width:0.414999;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;paint-order:stroke fill markers"
x="-2.6080971"
y="1.7071842"
id="text31"><tspan
sodipodi:role="line"
id="tspan31"
style="font-size:0.705556px;stroke-width:0.415"
x="-1.8942729"
y="1.7071842">akce</tspan></text><rect
style="opacity:1;fill:#951e7a;fill-opacity:1;stroke:none;stroke-width:0.414999;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;paint-order:stroke fill markers"
id="rect32"
width="1.672105"
height="1.2511554"
x="-4.501821"
y="2.6939824" /><text
xml:space="preserve"
style="font-size:0.705556px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;opacity:1;fill:#951e7a;fill-opacity:1;stroke:none;stroke-width:0.414999;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;paint-order:stroke fill markers"
x="-2.6360023"
y="3.5261946"
id="text32"><tspan
sodipodi:role="line"
id="tspan32"
style="font-size:0.705556px;fill:#951e7a;fill-opacity:1;stroke-width:0.415"
x="-2.6360023"
y="3.5261946">lokality</tspan></text><path
id="path32"
style="opacity:1;fill:#00b200;stroke-width:0.615;paint-order:stroke fill markers;stroke:none;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none"
d="M 3.3486328 2.4970052 L 3.3486328 3.8323242 L 2.7424683 3.8323242 L 4.2085286 5.738151 L 5.674589 3.8323242 L 5.0684245 3.8323242 L 5.0684245 2.4970052 L 3.3486328 2.4970052 z "
inkscape:export-filename="path32.png"
inkscape:export-xdpi="3000"
inkscape:export-ydpi="3000" /></g></svg>

After

Width:  |  Height:  |  Size: 6.3 KiB