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:
##Nazwa grupy=group
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:
##nazwa_zmiennej=typ_danych [opcje]
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:
##warstwa_punktowa=vector point
##warstwa=vector ##pole_tabeli=field warstwa
##typ_dzialki=selection budowlana;rolnicza;woda powierzchniowa;nieznany
##liczba=number 4 ##liczba_rzeczywista=number 2.5
Liczby rzeczywiste należy podawać z kropką;
##uklad=crs EPSG:2180
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:
##warstwa_wyjsciowa=output vector ##liczba_iteracji=output number
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:
##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()
Drugą grupą funkcji pomocniczych są funkcje pozwalające tworzyć nowe warstwy rastrowe, wektorowe i tabele. Znajdują się one w module processing.core.
##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
Istnieje również możliwość wykorzystania dostępnych algorytmów wtyczki Processing. W tym celu należy wywołać funkcję runalg z odpowiednimi parametrami:
##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)
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:
>>> 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 ...
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.:
>>> processing.alglist('buffer') Fixed distance buffer------------------->qgis:fixeddistancebuffer Variable distance buffer---------------->qgis:variabledistancebuffer Grid buffer----------------------------->saga:gridbuffer Grid proximity buffer------------------->saga:gridproximitybuffer ...
Aby uzyskać szczegółowe informacje odnośnie konkretnego algorytmu należy skorzystać z funkcji alghelp np.:
>>> processing.alghelp('qgis:fixeddistancebuffer') ALGORITHM: Fixed distance buffer INPUT DISTANCE SEGMENTS DISSOLVE OUTPUT
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.
>>> 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)
Opcje te można wylistować również funkcją algoptions(nazwa_algorytmu). Aby je ustawić należy podać numer danej opcji według kolejności:
processing.runlag("saga:slopeaspectcurvature", raster, 1, nachylenie, ...)
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:
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)
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:
##dzielnik=number 0 from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException if dzielnik == 0: raise GeoAlgorithmExecutionException(u'Dzielenie przez zero!') ...
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.