Scriptare în Python pentru Cadrul de Procesare¶
Atenționare
O nouă versiune a acestui tutorial este disponibilă la Scriptare în Python pentru Cadrul de Procesare (QGIS3)
Se pot crea script-uri pyqgis independente, care pot fi executate prin intermediul Consolei Python din QGIS. Cu puține modificări, puteți rula script-urile prin intermediul Cadrului de Procesare. Acest lucru are mai multe avantaje. În primul rând, preluarea datelor de la utilizator și scrierea fișierelor de ieșire este mult mai ușoară, deoarece Cadrul de Procesare oferă o interfață de utilizator standardizată pentru acestea. În al doilea rând, având script-ul în Bara de Instrumente de Procesare, este posibil ca acesta să facă parte din orice Model de Procesare sau să ruleze în serie, pentru mai multe intrări. Acest tutorial vă arată cum să scrieți un script Python personalizat, care să facă parte din Cadrul de Procesare din QGIS.
Privire de ansamblu asupra activității¶
Script-ul nostru va efectua o operație de dizolvare bazată pe un câmp ales de utilizator. De asemenea, va însuma valorile altui câmp pentru entitățile dizolvate. În cadrul exemplului vom dizolva un fișier shape al lumii în funcție de atributul SUBREGIUNE
, apoi vom însuma câmpul POP_EST
pentru a calcula totalul populației din regiunea dizolvată.
Notă
Dacă doriți să știți cum se face o operație de dizolvare împreună cu Statisticile, puteți folosi excelentul plugin DissolveWithStats
. Acest script este o demonstrație despre cum să puneți în aplicare o funcționalitate similară prin intermediul unui script de Procesare.
Obținerea datelor¶
Vom folosi setul de date Admin 0 - Țări de la Natural Earth.
Vom folosi setul de date Admin 0 - fișierul shape al țărilor.
Sursa de date [NATURALEARTH]
Pentru comoditate, puteți descărca o copie a setului de date direct de la adresa de mai jos:
Procedura¶
În QGIS, mergeți la
. Navigați la fișierul descărcatne_10_admin_0_countries.zip
și încărcați stratulne_10_admin_0_countries
. Mergeți la .
Extinteți grupul Scripts din Processing Toolbox și selectați Create a new script.
Pentru ca un script Python să fie recunoscut ca un script de Procesare, la începutul script-ului trebuie să se afle specificațiile de intrare și de ieșire. Acestea vor fi utilizate la construirea interfeței cu utilizatorul, pentru a rula script-ul. Puteți afla mai multe despre formatul acestor linii, din Documentația Processing din QGIS. Introduceți următoarele linii în Script editor. Aici avem 3 intrări ale utilizatorului:
dissolve_layer
,dissolve_field
șisum_field
. Rețineți cădissolve_layer
se adaugă după definițiile ambelor câmpuri de intrare. Acest lucru înseamnă că intrările vor fi pre-populate prin alegerea câmpurilor dindissolve_layer
. De asemenea, specificațioutput_layer
ca și strat vectorial de ieșire. Faceți clic pe butonul Save.
##dissolve_layer=vector
##dissolve_field=field dissolve_layer
##sum_field=field dissolve_layer
##output_layer=output vector
Denumiți script-ul
dissolve_with_sum
și salvați-l în locația implicită din folderul .
Înapoi, în Script editor, faceți clic pe butonul Run algorithm, pentru a previzualiza interfața utilizatorului.
Puteți vedea că doar prin adăugarea a câtorva rânduri, avem o interfață frumoasă, pe care utilizatorul va preciza intrările. De asemenea, este în concordanță cu toți ceilalți algoritmi de procesare, astfel încât nu există nici o curbă de învățare implicată în folosirea algoritmului personalizat.
În: guilabel: Script editor, introduceți următorul cod. Veți observa că apelăm unele metode speciale, cum ar fi
processing.getObject()
șiprocessing.features()
. Acestea sunt ambalate confortabil, pentru a ușura lucrul cu datele. Puteți afla mai multe despre acestea din secțiunea Funcțiilor suplimentare de manipulare a datelor a Documentației de Procesare QGIS. Clic pe Save pentru a salva codul nou introdus, și apoi pe butonul X pentru a închide editorul.
Notă
Acest script folosește în mod extensiv comprehensiunea listelor python. Aruncați o privire la acest tutorial pentru a înțelege listele comprehensive, și pentru a vă familiariza cu sintaxa.
from qgis.core import *
from PyQt4.QtCore import *
inlayer = processing.getObject(dissolve_layer)
dissolve_field_index = inlayer.fieldNameIndex(dissolve_field)
sum_field_index = inlayer.fieldNameIndex(sum_field)
# Find unique values present in the dissolve field
unique_values = set([f[dissolve_field] for f in
processing.features(inlayer)])
print unique_values
În timp ce se scrie codul, este important să fiți în măsură să vedeți erorile și să depanați codul. Script-urile de Procesare pot fi depanate cu ușurință prin intermediul consolei Python încorporate. În fereastra principală a QGIS, mergeți la Instrumentarul Processing și faceți dublu clic pe el pentru a-l lansa.
. O dată ce consola este deschisă, găsiți script-ul în
Selectați
SUBREGIUNE
ca și câmp de dizolvare. Puteți alege orice câmp și ca câmp de însumare atât timp cât scriptul nu are nici un cod pentru a interacționa cu acesta. Clic Run.
Veți vedea un dialog de eroare. Acest lucru este de așteptat, deoarece script-ul este incomplet și nu generează nici o ieșire încă.
În principalele ferestrele QGIS, veți vedea ieșirea de depanare a script-ului afișat în consolă. Acest lucru este un mod util de a adăuga instrucțiuni de imprimare și de a vedea valorile variabile intermediare.
Să ne întoarcem la editarea script-ului printr-un clic dreapta pe script, apoi selectați Edit script.
Introduceți codul de mai jos pentru a finaliza script-ul. Rețineți că folosim algoritmul existent de dizolvare din QGIS, prin procesarea cu ajutorul metodei
processing.runalg()
.
# Create a dictionary to hold values from the sum field
sum_unique_values = {}
attrs = [f.attributes() for f in processing.features(inlayer)]
for unique_value in unique_values:
val_list = [ f_attr[sum_field_index] for f_attr in attrs if f_attr[dissolve_field_index] == unique_value]
sum_unique_values[unique_value] = sum(val_list)
# Run the regular Dissolve algorithm
processing.runalg("qgis:dissolve", dissolve_layer, "false",
dissolve_field, output_layer)
# Add a new attribute called 'SUM' in the output layer
outlayer = processing.getObject(output_layer)
provider = outlayer.dataProvider()
provider.addAttributes([QgsField('SUM', QVariant.Double)])
outlayer.updateFields()
# Set the value of the 'SUM' field for each feature
outlayer.startEditing()
new_field_index = outlayer.fieldNameIndex('SUM')
for f in processing.features(outlayer):
outlayer.changeAttributeValue(f.id(), new_field_index, sum_unique_values[f[dissolve_field]])
outlayer.commitChanges()
Rulează algoritmul prin selectarea
SUBREGIUNII
ca și câmp dizolvat, șiPOP_EST
ca și câmp însumat. Clic pe Run.
Notă
Algoritmul de procesare poate dura până la 10 minute pentru a termina, în funcție de sistemul dumneavoastră.
După ce prelucrarea se încheie, puteți folosi instrumentul de Identificare, pentru a efectua clic pe orice poligon. Veți vedea adăugat noul câmp,
SUM
, cu valorilePOP_EST
adăugate din toate poligoanele originale.
Veți observa că toate celelalte câmpuri ale rezultatului sunt încă prezente. Când se dizolvă mai multe entități pentru a crea o singură entitate, nu are sens să se păstreze câmpurile originale în rezultat. Mergeți înapoi la: guilabel: Script editor și adăugați următorul cod pentru a șterge toate domeniile, cu excepția câmpului
SUM
și a câmpului care a fost folosit pentru a dizolva stratul original. Faceți clic pe butonul Save și închideți fereastra.
# Delete all fields except dissolve field and the newly created 'SUM' field.
outlayer.startEditing()
fields_to_delete = [fid for fid in range(len(provider.fields())) if fid != new_field_index and fid != dissolve_field_index]
provider.deleteAttributes(fields_to_delete)
outlayer.updateFields()
outlayer.commitChanges()
Una dintre funcționalitățile ascunse ale Cadrului de Procesare este aceea că toți algoritmii pot lucra pe entitățile selectate ale unui strat. Acest lucru este foarte util atunci când doriți să rulați un algoritm pe subsetul unui strat. Deoarece script-ul nostru folosește metoda
processing.features()
pentru a citi entitățile, se va respecta selecția curentă. Pentru a demonstra aceasta, haideți să facem mai întâi o selecție. Faceți clic pe butonul Selectare entități utilizând o expresie.
Introduceți următoarea expresie pentru a selecta entitățile din America de Nord și cea din Sud, apoi faceți clic pe Select.
"CONTINENT" = 'North America' OR "CONTINENT" = 'South America'
Veți vedea entitățile selectate, evidențiate cu galben. Efectuați clic-dreapta pe script-ul
dissolve_with_sum
, apoi selectați Execute.
Selectați intrările ca mai înainte, apoi efectuați clic pe Run.
Un nou
strat de ieșire
va fi adăugat în QGIS. Acesta va conține geometriile dizolvate numai din entitățile selectate din stratul de intrare. Observați, de asemenea, căstratul de ieșire
va conține numai 2 câmpuri, cum era de asteptat.
O ultimă, dar importantă activitate, o reprezintă documentarea algoritmului nostru. Cadrul de Procesare dispune de instrumente plăcute pentru a scrie și accesa Ajutorul. Mergeți la Script editor și faceți clic pe butonul Edit script help.
Completați detaliile pentru diferite elemente și faceți clic pe OK. Un ajutor detaliat va fi disponibil pentru toți utilizatorii script-ului în fila Help, atunci când se va lansa algoritmul.
Mai jos este script-ul complet. Îl puteți modifica pentru a se potrivi cerințelor dumneavoastră.
##dissolve_layer=vector
##dissolve_field=field dissolve_layer
##sum_field=field dissolve_layer
##output_layer=output vector
from qgis.core import *
from PyQt4.QtCore import *
inlayer = processing.getObject(dissolve_layer)
dissolve_field_index = inlayer.fieldNameIndex(dissolve_field)
sum_field_index = inlayer.fieldNameIndex(sum_field)
# Find unique values present in the dissolve field
unique_values = set([f[dissolve_field] for f in processing.features(inlayer)])
# Create a dictionary to hold values from the sum field
sum_unique_values = {}
attrs = [f.attributes() for f in processing.features(inlayer)]
for unique_value in unique_values:
val_list = [ f_attr[sum_field_index] for f_attr in attrs if f_attr[dissolve_field_index] == unique_value]
sum_unique_values[unique_value] = sum(val_list)
# Run the regular Dissolve algorithm
processing.runalg("qgis:dissolve", dissolve_layer, "false",
dissolve_field, output_layer)
# Add a new attribute called 'SUM' in the output layer
outlayer = processing.getObject(output_layer)
provider = outlayer.dataProvider()
provider.addAttributes([QgsField('SUM', QVariant.Double)])
outlayer.updateFields()
# Set the value of the 'SUM' field for each feature
outlayer.startEditing()
new_field_index = outlayer.fieldNameIndex('SUM')
for f in processing.features(outlayer):
outlayer.changeAttributeValue(f.id(), new_field_index, sum_unique_values[f[dissolve_field]])
outlayer.commitChanges()
# Delete all fields except dissolve field and the newly created 'SUM' field
outlayer.startEditing()
fields_to_delete = [fid for fid in range(len(provider.fields())) if fid != new_field_index and fid != dissolve_field_index]
provider.deleteAttributes(fields_to_delete)
outlayer.updateFields()
outlayer.commitChanges()
If you want to give feedback or share your experience with this tutorial, please comment below. (requires GitHub account)