One can write standalone pyqgis scripts that can be run via the Python Console in QGIS. With a few tweaks, you can make your standalone scripts run via the Processing Framework. This has several advantages. First, taking user input and writing output files is far easier because Processing Framework offers standardized user interface for these. Second, having your script in the Processing Toolbox also allows it to be part of any Processing Model or be run as a Batch job with multiple inputs. This tutorial will show how to write a custom python script that can be part of the Processing Framework in QGIS.
Skript kita akan melakukan sebuah operasi dissolve berdasarkan sebuah field yang dipilih oleh user. Ini juga akan menjumlahkan nilai dari field lain untuk fitur yang terdissolve atau larut. Pada contoh ini, kita akan mendissolve sebuah shapefile dunia berdasarkan attribut SUBREGION
dan menjumlahkan field POP_EST
untuk menghitung total populasi pada wilayah yang terdissolve.
Catatan
Jika anda mencoba untuk melakukan operasi dissolve dengan statistiknya, anda dapat menggunakan plugin DissolveWithStats
. Skrip ini adalah sebuah demonstrasi bagaimana mengimplementasikan fungsi serupa melalui sebuah skript processing.
Kita akan menggunakan dataset Admin 0 - Countries dari Natural Earth.
Unduh Admin 0 - countries shapefile..
Sumber Data: [NATURALEARTH]
Untuk kenyamanan, anda bisa secara langsung mengunduh sebuah kopi dari kedua dataset dari link di bawah:
Buka QGIS dan akses ne_10_admin_0_countries.zip
dan buka layer ne_10_admin_0_countries
. Akses .
Telusuri grup Scripts pada Processing Toolbox dan pilih Create a new script.
Untuk sebuah skript python agar bisa dikenal sebagai skrip processing, permulaan skrip adalah spesifikasi dari indput dan output. Ini akan digunakan untuk mengkonstruksi user interface untuk menjalankan skript. Anda dapat belajar lebih banyak tentang format dari hal ini dari QGIS Processing Documentation . Masukkan lines berikut pada Script editor . Disini kita menspesifikasi 3 input dari user: dissolve_layer
, dissolve_field
dan sum_field
. Perhatikan bahwa kita menambahkan dissolve_layer
setelah kedua field memasukkan definisi. Ini berarti bahwa input akan semacam dikumpulkan dengan pilihan field dari dissolve_layer
. Kita juga akan menentukan output_layer
sebagai layer output. Klik tombol Save
##dissolve_layer=vector
##dissolve_field=field dissolve_layer
##sum_field=field dissolve_layer
##output_layer=output vector
dissolve_with_sum
and save it at the default location
under folder.processing.getObject()
and processing.features()
. These are convenience wrappers that make it
easy to work with data. You can learn more about these from Additional
functions for handling data
section of QGIS Processing Documentation. Click Save to save the
newly entered code and then the X button to close the editor.Catatan
This script uses python list comprehensions extensively. Take a look at this list comprehension tutorial to get familiar with the syntax.
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
SUBREGION
as the dissolve field. You may choose any
field as the sum field as the script doesn’t have any code yet
to deal with it. Click Run.processing.runalg()
method.# 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()
SUBREGION
as the dissolve
field and POP_EST
as the sum field. Click Run.Catatan
The processing algorithm may take upto 10 minutes to finish depending on your system.
SUM
field with the
POP_EST
values from all original polygons added up.SUM
field and the field that was used to dissolve the
original layer. Click Save button and close the window.# 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()
processing.features()
method to read features, it will respect the
current selection. To demonstrate that, let’s make a selection first. Click
on the Select features using an expression button."CONTINENT" = 'North America' OR "CONTINENT" = 'South America'
dissolve_with_sum
script and select Execute.output layer
will be added to QGIS. This will contain dissolved
geometries only from the selected features in the input layer. You will
also note that the output layer
will contain only 2 fields as expected.Below is the complete script for reference. You may modify it to suit your needs.
##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()
This work is licensed under a Creative Commons Attribution 4.0 International License