04. QGIS - tvorba zásuvného modulu¶
V této části se zaměříme na tvorbu zásuvných modulů pro software QGIS.
Založme zásuvný modul na posledním příkladu z minulého cvičení. Pro větší přehlednost tak učiníme v následujících krocích. Takový postup je doporučován z toho důvodu, že se řeší zvlášť možné problémy vzniknuvší při implementaci funkcionality a při tvorbě zásuvného modulu.
- tvorba funkce
- ze skriptu vytvoříme funkci
- parametrizujeme funkci
- rozšíříme funkci o další zamýšlenou funkcionalitu
- implementujme funkci jako součást zásuvného modulu
Tvorba funkce k vytvoření obalové vrstvy¶
Připomeňme si, jak vypadal skript, který vytvářel obalovou zónu kolem
bodů z vrstvy lucas
a vypisoval jejich obsah.
from qgis.core import QgsProject
# mapLayersByName() vraci seznam
for feature in QgsProject.instance().mapLayersByName('lucas')[0].getFeatures():
if feature['obs_dist']: # nutno pokud jsou nektere prvky NULL
# druhym parametrem je pocet lomovych bodu pouzitych k vytvoreni kruznice
# (jedna se o body navic ke ctyrem potrebnym pro ctverec)
buffer = feature.geometry().buffer(feature["obs_dist"], 5)
point = feature.geometry().asPoint()
print(f'{feature["point_id"]}: [{point.x()}, {point.y()}]: {buffer.area()} m2')
Tvorba funkce je jednoduchá.
from qgis.core import QgsProject
def lucas_buffer():
# mapLayersByName() vraci seznam
for feature in QgsProject.instance().mapLayersByName('lucas')[0].getFeatures():
if feature['obs_dist']: # nutno pokud jsou nektere prvky NULL
# druhym parametrem je pocet lomovych bodu pouzitych k vytvoreni kruznice
# (jedna se o body navic ke ctyrem potrebnym pro ctverec)
buffer = feature.geometry().buffer(feature["obs_dist"], 5)
point = feature.geometry().asPoint()
print(f'{feature["point_id"]}: [{point.x()}, {point.y()}]: {buffer.area()} m2')
if __name__ == '__console__':
lucas_buffer()
Přestože však byla tvorba funkce jednoduchá, dává nám mnoho možností. Pro opětovné použití funkce na jiných vrstvách je zajisté záhodno ji parametrizovati. Zároveň v případě, že není vstupní vrstva nalezena, vyvoláme vyjímku.
Úkol
Přepišme funkci tak, aby vyvolávala vyjímku i v případě, že je nalezeno více vrstev stejného názvu.
Vytvoření výstupní vektorové vrstvy¶
Vytvořme novou funkci create_new_layer
, která na základě
specifikace (typ geometrie a souřadnicový systém, struktura atributové
tabulky) vytvoří novou vektorovou vrstvu. Takto vytvořenou vrstvu na
konci skriptu přidejme do mapové okna.
Dále upravme funkci lucas_buffer
tak, aby vytvářela nové
prvky obalové zóny a zapisovala je včetně relevatních atributů do nové
vektorové vrstvy vytvořené voláním funkce create_new_layer
.
Úkol
Přepišme funkci tak, aby souřadnicový systém výstupní vrstvy byl odvozen z vektorové vrstvy vstupní.
Tvorba zásuvného modulu¶
Nejprve nainstalujme dva nové zásuvné moduly:
- Plugin Builder - použijeme pro vytvoření šablony pluginu
- Plugin Reloader - tento plugin umožní znovunačíst již zavedený zásuvný modul. To nám zásadně usnadní vývoj a testování našeho zásuvného modulu v prostředí QGISu.
Vytvoření šablony zásuvného modulu¶
Spustíme Plugins > Plugin Builder
a pomocí jednoduchého průvodce
vytvořme šablonu našeho zásuvného modulu.
V prvním kroku dejinujme:
Class name
- název Python třídy implementující zásuvný modul (bez diakritiky, mezer a pod)Plugin name
- název zásuvného modulu, tak jak se bude zobrazovat v menuDescription
- krátký popis modulu, tak jak se bude zobrazovat v dialoguPlugins
Module name
- název Python modulu a zároveň adresáře se zásuvným modulem (bez diakritiky, mezer a pod)Version number
- verze zásuvného moduluMinimum QGIS version
- minimální verze QGIS nutná pro fungování zásuvného moduluAuthor/Company
- autor zásuvného moduluEmail address
- kontakt na autora
Poznámka
Položky Description
, Version number
, Minimum QGIS version
, Author/Company
a Email adress
lze jednoduše změnit po vytvoření zásuvného modulu v souboru metadata.txt
.
V dalším kroku popišme funcionalitu zásuvného modulu. Tato informace
se bude zobrazovat v dialogu Plugins
. Popis lze změnit po
vytvoření zásuvného modulu v souboru metadata.txt
.
V následujícím kroku definujme způsob začlenění zásuvného modulu do prostředí QGISu. Máme tři možnosti:
Tool button with dialog
- dialog s tlačítkemTool button with dock widget
- připnutelné okno s tlačítkemProcessing provider
- integrace do nástrojů zpracování
V našem případě zvolme připnutelné okno s tlačítkem.
Dále definujme podpůrné komponenty zásuvného modulu. Typicky je pro nás důležitá:
Internatialization
v případě, že plánuje zásuvný modul lokalizovat do různých jazykůpb_tool
usnadní sestavení zásuvného modulu do formy zip archivu a jeho publikaci v repozitáři zásuvných modulů QGIS
Mezi povinné informace patří i odkaz na repozitár se zdrojovým kódem
zásuvného modulu, na systém pro hlášení chyb, domovskou stránku a
klíčová slova. Všechny tyto položky lze jednoduše změnit po vytvoření
zásuvného modulu v souboru metadata.txt
.
Na poslední stránce průvodce zvolíme adresář, do kterého se nově vytvořený plugin vytvoří.
Načtení zásuvného modulu v QGIS¶
Ve výchozím nastavení QGIS při startu vyhledává zásuvné moduly v profilu uživatele. V nastavení ale můžeme přidat i další adresáře, ve kterých bude zásuvné moduly vyhledávat. To se nám bude pří dalším vývoji a testování zásuvného modulu hodit.
V dialogu Settings > Options
, záložce System
sekci
Enviroment
definujme proměnou prostředí QGIS_PLUGINPATH
. Tato
proměnná bude odkazovat na adresář, ve kterém je umístěn podadresář se
zásuvným modulem.
Todo
Přidat screenshot s načteným pluginem
Definice uživatelského rozhraní¶
Výchozí uživatelské rozhraní bude velice minimalistické. Bylo by vhodné jej doplnit o potřebné vstupní parametry:
- vstupní vektorová vrstva
- výstupní vektorová vrstva
- tlačítko, které zásuvný modul spustí
Lze tak učiniti dvěma různými způsoby. Za využití programovacího jazyka Python (PyQt
), nebo za pomoci nástroje Qt Designer. Přidejme jednotlivé prvky v programu Qt Designer. Tím si ukážeme jeho výhody (jednoduché a intuitivní ovládání), ale i nevýhody (jest vhodný pro rychlý návrh, ale nejsme v něm schopni vytvořit složitější signály a zdířky). Jeden, nikoli však jediný, z možných návrhů může nakonec vypadati následujícím způsobem.
Funkcionalita zásuvného modulu¶
Ačkoli jsme si vytvořili oku lahodící grafické uživatelské rozhraní, rádi bychom mu dodali potřebnou funkcionalitu. Upravme soubor fgis_plugin/fgis_plugin.py
tak, aby se po stisknutí tlačítka Run
spustila funkce lucas_buffer
. Po vygenerování vypadá soubor následujícím způsobem.
Přidejme tlačítku run_button
odpovídající signál. Abychom mohli importovat funkci lucas_buffer
, uložme si náš dosavadní skript pod názvem lucas_tools
do adresáře se zásuvným modulem. Po našich úravách by měl skript vypadati podobně jako v následujícím příkladu.
Úkol
Upravte funkce v souboru lucas_tools
tak, aby nebylo v fgis_plugin_dockwidget.py
zapotřebí duplikovat kód pro definici nové vrstvy.
Úprava zásuvného modulu¶
Zásuvný modul rozšiřme o novou funkcionalitu - stažení fotografií pro vybrané LUCAS body.
Fotografie dostupné pro zvolené LUCAS body můžeme jednoduše stáhnout pomocí Python balíčku st-lucas. Tento balíček doinstalujeme:
Nejprve vyzkoušejme stažení fotografií pro daný bod LUCAS a rok měření:
from zipfile import ZipFile
from st_lucas import LucasIO
point_id = 46682050
target_dir = "/home/martin/Downloads"
lucasio = LucasIO()
lucasio.data = "/home/martin/Downloads/lukas_sample.gpkg"
images = lucasio.get_images(2018, point_id)
filename = lucasio.download_images(images, target_dir)
with ZipFile(filename) as zip:
zip.extractall(target_dir)
Na základě toho rozšířme zdrojový kód o novou funkci
unzip_lucas_photos()
. Dále modifikujme funkci
lucas_buffer_photo()
tab, aby fotografie byly staženy a rozbaleny
do cílového adresáře v následující struktuře (pointid_year
):
Do atributové tabulky výstupní vrstvy přidejme nový atribut photo
odkazující na soubor P.jpg
.
Úkol
Upravme funkci tak, aby nestahovala zip archiv s fotografiemi opakovaně.
Tip
Fotografie může být zobrazena přímo v atributové tabulce.
Ve vlastnostech vrstvy (Attributes Form
) nastavíme: Widget Type
na Attachment
a Integrated Document Viewer Type
na Image
.
Po otevření atributové tabulky se přepneme do režimu formuláře.
Úkol
Upravte zásuvný modul tak, aby byl attribut photo
nastaven automaticky na Attachment
a Image
.
Úkol
Vyzkoušejte vytvořit další zásuvný modul. Můžete čerpat z materiálů školení skupiny GISMentors.
Publikace zásuvného modulu¶
Vytvořený zásuvný modul můžeme s kolegy sdílet ve formě zip
archivu. Ten lze jednoduše nainstalovat z Plugins > Manage and
Install Plugins... > Install from ZIP
.
Zip archiv se zásuvným modulem lze vytvořit pomocí nástroje
pb_tool
. Nejprve jej doinstalujeme:
Nástroj poskytuje celou řadu voleb (podrobné informace můžete vypsat
pomocí pb_tool --help
). Nám postačí pb_tool zip
pro vytvoření
zip archivu.
V našem případě jsme do struktury zásuvného modulu přidali soubor
lucas_tools.py
. Ten musíme začlenit do konfigurace pb_tool.cfg
:
Poznámka
Pokud nemáme sepsánu dokumentaci (adresář help
), tak můžeme její sestavení vypnout. Zakomentujeme řádek:
Poznámka
V případě, že jste měnili ikonku zásuvného modulu (icon.png
) je nutné spustit
Poté můžeme vytvořit zip archiv.
Soubor se vytvoří v adresáři zip_build
.
Úkol
Vyzkoušejte instalaci zásuvného modulu z vytvořeného zip archivu.
QGIS plugins web portal
V případě, že jsme se zásuvným modulem spokojeni a chceme jej sdílet s
ostatními uživateli QGIS, tak je tu možnost jej publikovat na webovém
portálu QGIS. Zásuvný modul bude ve výsledku snadno
instalovatelný z Plugins > Manage and Install Plugins...
.
Postup: Nejprve si vytvoříme na webovém portálu učet https://plugins.qgis.org/accounts/login/ a poté zásuvný modul nahrajeme ve formě zip archivu. Zásuvný modul projde hodnocením. V případě, že splní všechny podmínky (licence GNU GPL, dokumentace, ...) bude schálen a tím se stane snadno dostupný pro další uživatele QGISu.