Python-scripts schrijven voor framework Processing¶
Waarschuwing
Een nieuwe versie van deze handleiding is beschikbaar op Python-scripts schrijven voor framework Processing (QGIS3)
Men kan zelfstandige scripts in Pyqgis schrijven die kunnen worden uitgevoerd in de Python Console in QGIS. Met een aantal aanpassingen kunt u uw scripts voor Pyqgis ook uitvoeren via het framework Processing. Dat heeft een aantal voordelen. Ten eerste is het invoeren van invoer door de gebruiker en het schrijven van uitvoerbestanden veel eenvoudiger omdat het framework Processing hier een gestandaardiseerde gebruikersinterface voor biedt. Ten tweede, door uw script te hebben in de Processing Toolbox kan het ook deel uitmaken van elk Model voor Processing of worden uitgevoerd als een Batch-taak met meerdere invoer. Deze handleiding zal laten zien hoe een aangepast script voor Python te schrijven dat deel kan uitmaken van het framework Processing in QGIS.
Overzicht van de taak¶
Ons script zal een bewerking voor ontbinden uitvoeren, gebaseerd op een door de gebruiker gekozen veld. Het zal ook de waarden van een ander veld bij elkaar optellen voor de ontbonden objecten. In het voorbeeld zullen we een shapefile van de wereld ontbinden, gebaseerd op een attribuut SUBREGION
en het veld POP_EST
optellen om de totale bevolking in de ontbonden regio te berekenen.
Notitie
Als u zoekt naar een mogelijkheid om een bewerking Dissolve naast Statistieken uit te voeren, kunt u de excellente plug-in DissolveWithStats
gebruiken. Dit script is een demonstratie van hoe een soortgelijke functionaliteit te implementeren via een script voor Processing.
De gegevens ophalen¶
We zullen de gegevensset Admin 0 - Countries van Natural Earth gebruiken.
Download het Admin 0 - countries shapefile..
Gegevensbron [NATURALEARTH]
Voor het gemak kunt u direct een kopie van de gegevensset downloaden vanaf de links hieronder:
Procedure¶
Open QGIS en ga naar
. Blader naar het gedownloade bestandne_10_admin_0_countries.zip
en laadt de laagne_10_admin_0_countries
. Ga naar .

Vergroot de groep Scripts in de Processing Toolbox en selecteer Nieuw script aanmaken.

Het begin van het script moet voldoen aan de specificaties voor invoer en uitvoer om een script voor Python te kunnen laten herkennen als een script voor Processing. Dat zal worden gebruikt om de gebruikersinterface te construeren om het script uit te voeren. U kunt meer te weten komen over de indeling van deze regels in de QGIS Processing-documentatie. Voer de volgende regels in de Script editor in. Hier specificeren we 3 gebruikersinvoeren:
dissolve_layer
,dissolve_field
ensum_field
. Merk op dat wedissolve_layer
toevoegen na de beide definities voor veldinvoer. Dit betekent dat de invoer vooraf zal worden gevuld met de keuze van de velden indissolve_layer
. We specificeren ook deoutput_layer
als de uitvoer vectorlaag. Klik op de knop Opslaan.
##dissolve_layer=vector
##dissolve_field=field dissolve_layer
##sum_field=field dissolve_layer
##output_layer=output vector

Noem het script
dissolve_with_sum
en sla het op op de standaard locatie in de map .

Klik, terug in de Script editor, op de knop Start algoritme om een voorbeeld te zien van de gebruikersinterface.

U ziet dat we, slechts door het toevoegen van een aantal regels, een keurige gebruikersinterface hebben om de invoer te kunnen specificeren. Het is ook consistent met alle andere algoritmes voor Processing, dus is er geen leercurve voor het gebruiken van uw eigen aangepaste algoritme.

Voer, in de Script editor, de volgende code in. Het zal u opvallen dat we enkele speciale methoden gebruiken zoals
processing.getObject()
enprocessing.features()
. Dit zijn wrappers voor het gemak die het eenvoudiger maken om met gegevens te werken. U kunt hier meer over te weten komen in het gedeelte Aanvullende functies voor het afhandelen van gegevens van de QGIS Processing-documentatie. Klik op Opslaan om de nieuw ingevoerde code op te slaan en dan op de knop X om de bewerker te sluiten.
Notitie
Dit script gebruikt zeer veel Python samenvattingen uit lijsten. Bekijk deze list comprehension tutorial eens om bekend te geraken met de syntaxis.
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

Bij het schrijven van code is het belangrijk om de fouten te kunnen zien en uw code te kunnen debuggen. Uw scripts voor Processing kunnen eenvoudig worden gedebugd via de ingebouwde Python Console. Ga, in het hoofdvenster van QGIS, naar Processing Toolbox en dubbelklik erop om het te starten.
. Zoek, als de console eenmaal is geopend, naar uw script in de

Selecteer
SUBREGION
als het dissolve field. U mag elk veld kiezen als het sum field omdat het script nog geen code heeft om dat af te handelen. Klik op Run.

U zult een dialoogvenster voor foutberichten zien. Dat werd verwacht omdat het script nog niet volledig is en nog geen uitvoer genereert.

In het hoofdvenster van QGIS zult u de uitvoer voor debuggen van het script zien afgedrukt in de console. Dit is een handige manier om argumenten voor afdrukken toe te voegen en tussenliggende waarden voor variabelen te zien.

Laten we terug gaan naar het bewerken van het script door met rechts te klikken op het script en te selecteren Script bewerken.

Voer de volgende code in om het script te voltooien. Merk op dat we het bestaande algoritme Dissolve in QGIS gebruiken via Processing met behulp van de methode
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()

Voer het algoritme uit door
SUBREGION
te selecteren als het dissolve field enPOP_EST
als het sum field. Klik op Run.
Notitie
Het algoritme van Processing kan tot 10 minuten nodig hebben om te voltooien, afhankelijk van uw systeem.

Als de verwerking is voltooid kunt u het gereedschap Objecten identificeren gebruiken en op een willkeurige polygoon klikken. U zult het nieuw toegevoegde veld
SUM
zien met de waarden vanPOP_EST
uit alle originele polygonen bij elkaar opgeteld.

U zult zien dat alle andere velden in de uitvoer nog steeds aanwezig zijn. Wanneer u vele objecten ontbindt om één enkel object te maken, heeft het geen zin om de originele velden in de uitvoer te behouden. Ga terug naar de Script editor en voeg de volgende toe om alle velden, met uitzondering van het veld
SUM
en het veld dat werd gebruikt om de originele laag te ontbinden, te verwijderen. Klik op de knop Opslaan en sluit het venster.
# 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()

Eén van de verborgen mogelijkheden van het framework Processing is dat alle algoritmes kunnen werken op geselecteerde objecten van een laag. Dat is enorm handig als u een algoritme wilt uitvoeren op een subset van een laag. Omdat ons script de methode
processing.features()
gebruikt om objecten te lezen, zal het de huidige selectie respecteren. Laten we, om dat te demonstreren, eerst een selectie maken. Klik op de knop Selecteren van objecten gebruik makend van een expressie.

Voer de volgende expressie in om objecten te selecteren uit Noord- en Zuid-Amerika en klik op Selecteren.
"CONTINENT" = 'North America' OR "CONTINENT" = 'South America'

U zult de geselecteerde objecten zien geaccentueerd in geel. Klik met rechts op het script
dissolve_with_sum
en selecteer Uitvoeren.

Selecteer de invoer zoals eerder en klik op Run.

Een nieuwe
output layer
zal worden toegevoegd aan QGIS. Deze zal alleen de ontbonden geometrieën bevatten uit de geselecteerde objecten van de invoerlaag. U zult ook zien dat deoutput layer
, zoals verwacht, slechts 2 velden zal bevatten.

Een laatste maar belangrijk resterend punt is om ons algoritme te documenteren. Het framework Processing heeft leuke gereedschappen om Help te schrijven en er toegang tot te verkrijgen. Ga naar de Script editor en klik op de knop Help-script bewerken.

Vul de details in voor de verschillende elementen en klik op OK. Nu zal een gedetailleerde Help beschikbaar zijn voor alle gebruikers van uw script op de tab Help als zij het algoritme starten.

Hieronder staat het volledige script als verwijzing. U kunt het aanpassen zodat het aan uw eigen wensen voldoet.
##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)