Wtyczka Processing (do wersji QGIS 1.8 SEXTANTE) zawiera wiele pomocnych narzędzi usprawniających pracę z danymi przestrzennymi w QGIS. Jednym z nich jest mechanizm pozwalający na tworzenie i uruchamianie przez użytkowników skryptów napisanych w języku programowania Python. Dzięki temu aby dodać nową funkcjonalność nie trzeba tworzyć nowej wtyczki, a przy tym martwić się o zbudowanie interfejsu, właściwe wypełnienie metadanych itp. Skrypty traktowane są przez Processing w ten sam sposób jak pozostałe algorytmy. Można je więc uruchomić w oknie dialogowym lub w trybie wsadowym jak również wykorzystać w graficznym modelarzu. Co więcej, w skryptach można wykorzystać już istniejące algorytmy.
Aby stworzyć nowy skrypt należy w oknie Narzędzia geoprocessingu rozwinąć pozycję Scripts ->Tools i podwójnie kliknąć na Create new script. Zostanie wyświetlony edytor skryptu. Posiada on kilka funkcji ułatwiających pisanie kodu źródłowego jak kolorowanie i autouzupełnianie składni, zwijanie/rozwijanie bloków kodu czy numerowanie linii. W górnej części okna dostępne są przyciski umożliwiające m.in. zapis zmian, edycję pomocy czy uruchomienie skryptu.
Na początku kodu można określić nazwę grupy, w której będzie wyświetlany skrypt w oknie Narzędzi geoprocessingu:
[code lang=”python”]##Nazwa grupy=group[/code]
Jeśli sami nie określimy grupy to skrypt zostanie przypisany do grupy User scripts.
Następnie należy określić pola do wprowadzania przez użytkownika niezbędnych parametrów. Każdy parametr określa się w jednej linii zaczynającej się znakami ##, następnie należy podać jego nazwę, typ danych oraz, w niektórych przypadkach, opcje:
[code lang=”python”]##nazwa_zmiennej=typ_danych [opcje][/code]
Nazwy zmiennych nie powinny zawierać spacji – zamiast niej należy wpisać podkreślnik – wtyczka automatycznie zamieni go w spację. Nie należy również korzystać ze znaków specjalnych, w tym polskich znaków diakrytycznych. Opcje pozwalają m.in. na ustawienie domyślnych wartości lub typu geometrii warstwy wektorowej, w większości przypadków nie są one jednak wymagane. Należy je oddzielić od typu danych pojedynczą spacją. Aktualnie dostępne są następujące typy danych:
Liczby rzeczywiste należy podawać z kropką;
Tak przedstawiają się powyższe kontrolki w oknie skryptu:
Dane wyjściowe określa się w taki samo sposób jak wejściowe. Jako typ danych należy podać output, natomiast jako opcję należy wpisać wybrany rodzaj:
[code lang=”python”]##warstwa_wyjsciowa=output vector
##liczba_iteracji=output number[/code]
Skrypt może mieć określonych wiele danych wyjściowych. Wartości przyjmowane przez zmienne wyjściowe to, w zależności od ich rodzaju, ścieżka dostępu do pliku (1-5), liczba (6) lub łańcuch znaków (7).
Dostęp do parametrów określonych przez użytkownika odbywa się poprzez odwołanie do zmiennej za pomocą zdefiniowanej na początku nazwy (stąd zakaz korzystania w nazwach zmiennych ze spacji i znaków specjalnych). Część danych jak liczby czy łańcuchy znaków są określone wprost tzn. w formie podanej w oknie skryptu. Aby mieć dostęp do pozostałych można skorzystać z dodatkowych funkcji udostępnianych przez wtyczkę Processing które ułatwiają pracę z danymi wejściowymi:
Poniższy przykład pozwala zapisać do pliku tekstowego unikalne wartości z tabeli atrybutów warstwy wektorowej:
[code lang=”python”]##input=vector
##pole=field input
##plik=output file
wektor = processing.getObject(input)
wartosci = processing.uniqueValues(wektor, pole)
f = open(plik, ‘w’)
try:
for wartosc in wartosci:
f.write(‘%s\n’ % str(wartosc))
finally:
f.close()
[/code]
Drugą grupą funkcji pomocniczych są funkcje pozwalające tworzyć nowe warstwy rastrowe, wektorowe i tabele. Znajdują się one w module processing.core.
[code lang=”python”]##input=vector
##output=output vector
from processing.core.VectorWriter import VectorWriter
vectorLayer = processing.getObject(input)
writer = VectorWriter(output, vectorLayer.dataProvider().encoding(), vectorLayer.pendingFields(),vectorLayer.wkbType(), vectorLayer.crs())
features = processing.features(vectorLayer)
for feat in features:
writer.addFeature(feat)
del writer[/code]
Istnieje również możliwość wykorzystania dostępnych algorytmów wtyczki Processing. W tym celu należy wywołać funkcję runalg z odpowiednimi parametrami:
[code lang=”python”]##input_raster=raster
##input_wektor=vector
##warstwa_wyjsciowa=output vector
wektor = processing.getObject(input_wektor)
raster = processing.getObject(input_raster)
processing.runalg(‘qgis:pointsfromlines’, raster, wektor, warstwa_wyjsciowa)[/code]
W powyższym przykładzie zmienne raster i wektor to odpowiednio instancje klas QgsRasterLayer i QgsVectorLayer uzyskane dzięki funkcji getObject.
W jaki sposób można uzyskać informacje o algorytmach? I w tym przypadku z pomocą przychodzi wtyczka Processing. Najprościej jest z nich korzystać za pomocą Konsoli Pythona QGIS.
Funkcja alglist wyświetla wszystkie dostępne algorytmy:
[code lang=”python”]>>> processing.alglist()
Add autoincremental field—————>qgis:addautoincrementalfield
Add field to attributes table———–>qgis:addfieldtoattributestable
Advanced Python field calculator——–>qgis:advancedpythonfieldcalculator
Basic statistics for numeric fields—–>qgis:basicstatisticsfornumericfields
Basic statistics for text fields——–>qgis:basicstatisticsfortextfields
Clip————————————>qgis:clip
…[/code]
Po lewej stronie wyświetlany jest krótki opis algorytmu, a po prawej stronie jego nazwa, którą należy użyć jako pierwszy parametr funkcji runlag. Możliwe jest ograniczenie wyników poprzez podanie tekstu (fragmentu nazwy lub opisu) jako parametru funkcji alglist() np.:
[code lang=”python”]>>> processing.alglist(‘buffer’)
Fixed distance buffer——————->qgis:fixeddistancebuffer
Variable distance buffer—————->qgis:variabledistancebuffer
Grid buffer—————————–>saga:gridbuffer
Grid proximity buffer——————->saga:gridproximitybuffer
…[/code]
Aby uzyskać szczegółowe informacje odnośnie konkretnego algorytmu należy skorzystać z funkcji alghelp np.:
[code lang=”python”]>>> processing.alghelp(‘qgis:fixeddistancebuffer’)
ALGORITHM: Fixed distance buffer
INPUT
DISTANCE
SEGMENTS
DISSOLVE
OUTPUT [/code]
Funkcja ta wyświetla opis algorytmu oraz jego parametry. Jeśli algorytm ma parametry typu <ParameterSelection>, czyli wybór z góry określonych opcji, dodatkowo na końcu znajduje się spis dostępnych wartości.
[code lang=”python”]>>> processing.alghelp("saga:slopeaspectcurvature")
ALGORITHM: Slope, aspect, curvature
ELEVATION
METHOD
SLOPE
ASPECT
CURV
HCURV
VCURV
METHOD(Method)
0 – [0] Maximum Slope (Travis et al. 1975)
1 – [1] Maximum Triangle Slope (Tarboton 1997)
2 – [2] Least Squares Fitted Plane (Horn 1981, Costa-Cabral & Burgess 1996)
3 – [3] Fit 2.Degree Polynom (Bauer, Rohdenburg, Bork 1985)
4 – [4] Fit 2.Degree Polynom (Heerdegen & Beran 1982)
5 – [5] Fit 2.Degree Polynom (Zevenbergen & Thorne 1987)
6 – [6] Fit 3.Degree Polynom (Haralick 1983)[/code]
Opcje te można wylistować również funkcją algoptions(nazwa_algorytmu). Aby je ustawić należy podać numer danej opcji według kolejności:
[code lang=”python” gutter=”false”]processing.runlag("saga:slopeaspectcurvature", raster, 1, nachylenie, …)[/code]
W powyższym przykładzie zostanie użyta metoda Maximum Triangle Slope.
W trakcie działania skryptu może zdarzyć się, że chcemy wyświetlić dodatkowe informacje o aktualnym postępie pracy. Jest to szczególnie przydatne przy czasochłonnych operacjach. Z pomocą przychodzi moduł progress, który udostępnia metody pozwalające ustawić procentowe zaawansowanie obliczeń lub opis aktualnych działań:
[notice]Funkcje setCommand, setDebugInfo i setConsoleInfo wyświetlą informacje w oknie tylko jeśli w opcjach Geoprocesingu zaznaczona jest opcja Show extra info in Log panel. Są one pomocne głównie przy tworzeniu skryptu, w ostatecznej wersji należy używać setInfo lub setText.[/notice]
Przykładowe użycie powyższych funkcji:
[code lang=”python”]from time import sleep
progress.setInfo(‘setInfo(tekst)’)
progress.setInfo(‘setInfo(tekst, True)’, True)
progress.setCommand(‘setCommand(tekst)’)
progress.setDebugInfo(‘setDebugInfo(tekst)’)
progress.setConsoleInfo(‘setConsoleInfo(tekst)’)
for i in range(10):
progress.setPercentage(i*10)
progress.setText(‘setPercentage: %d’ % (i*10))
sleep(0.5)[/code]
Jeżeli po uruchomieniu algorytmu wystąpi krytyczny błąd uniemożliwiający dalsze działanie należy go przerwać. W tym celu można wykorzystać klasę GeoAlgorithmExecutionException, która pozwala przerwać działanie skryptu oraz wyświetlić odpowiedni komunikat:
[code lang=”python”]##dzielnik=number 0
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
if dzielnik == 0:
raise GeoAlgorithmExecutionException(u’Dzielenie przez zero!’)
…
[/code]
Edytor pomocy pozwala przygotować opis algorytmu i jego parametrów. Można go wywołać przyciskiem . W górnej części wyświetlony jest podgląd pomocy. Poniżej, z lewej strony znajduje się lista elementów do edycji. Dostępne pozycje:
Po wybraniu pozycji w prawej części okna można wpisać treść pomocy dla danego elementu. Pliki pomocy mają taką samą nazwę jak skrypt, ale mają rozszerzenie .help.
Stworzone skrypty widoczne są w oknie Narzędzia geoprocessingu pod pozycją Scripts . Po zapisaniu można je używać jak pozostałe algorytmy lub wykorzystać w graficznym modelarzu lub innym skrypcie.
Domyślnie przechowywane one są w katalogu konfiguracyjnym QGIS /.qgis2/processing/scripts/. Ścieżkę tą można zmienić w opcjach geoprocesingu. Można je kopiować i przenosić na inne komputery jak zwykłe pliki.