This QGIS Python Tutorial series will discuss about how to get features of a vector layer, add or delete a field and updating attribute value. I think this tutorial is quite interesting because in the previous post already discussed how to add a vector layer into QGIS map canvas. Then working with features and attributes will enhance our capabilities to work with vector layer in QGIS. I'm using the vector layer of Parks polygon in Vancouver city, Canada in this tutorial. You can find this data at Vancouver City Data Catalog, otherwise you can also use your own data. For this tutorial I'm using QGIS 3.2 Bonn.
First step let's define the data as vector layer using QgsVectorLayer class as follow:
layer=QgsVectorLayer("F:\park_polygons.shp","park","ogr")
Then let's check fields name that available in the park layer. We will get a list that contains the name of field. Because it returned a list, later we can access the attribute values of a field using the list index.
print (layer.fields().names())
Output:
['PARK_NAME', 'PARK_ID', 'PARK_URL', 'AREA_HEC']
Now, let's print all the park's name using features attribute method. From the list we know that the park's name is the first value in the list, so it has index 0, cause List starts from 0.
features=layer.getFeatures() for f in features: print (f.attributes()[0])
Sample Output:
Aberdeen Park
Adanac Park
Alexandra Park
Alice Townley Park
Almond Park
Almond Park
Andy Livingstone Park
......
To print attributes for all fields, simply omitted the index.
features=layer.getFeatures() for f in features: print (f.attributes())
Sample Output:
'Tecumseh Park', 198, 'http://covapp.vancouver.ca/parkfinder/parkdetail.aspx?inparkid=198', '2.09']
['Templeton Park', 60, 'http://covapp.vancouver.ca/parkfinder/parkdetail.aspx?inparkid=60', '1.93']
Now let's play a little bit with a conditional term, for example we just want to know which park that has area more than 200 Ha. For this we make a loop to check each feature with has area more than 200 Ha and count the number.
#GET FEATURE WITH AREA GREATER THAN 200 HA features=layer.getFeatures() n_total=0 n_200=0 for f in features: n_total +=1 area_hec=f.attributes()[1] if area_hec > 200: print (f.attributes()[0], "Area(Ha): ", area_hec) n_200 +=1 print (f"Number of Parks with area > 200 Ha: {n_200} From {n_total} ")
Sample Output:
.......
Trillium Park Area(Ha): 245
West Point Grey Park Area(Ha): 221
Westmount Park Area(Ha): 222
Yaletown Park Area(Ha): 237
Number of Parks with area > 200 Ha: 47 From 264
Adding New Field
To add a new field for a vector layer can done using addAttributes method from QgsVectorDataProvider. That's why we need to instantiate the vector layer to vector data provider using dataProvider method. After that using addAttributes method then a field is added using QgsField class with taken two parameters: Field Name and Type. For field's type can be defined using QVariant. Lastly we have to call updateFields method to update the layer.
For example in this tutorial we want to add a field with name Length which later contains each park boundary length. The code can be seen as follow:
#ADDING NEW FIELD from PyQt5.QtCore import QVariant layer_provider=layer.dataProvider() layer_provider.addAttributes([QgsField("Length",QVariant.Double)]) layer.updateFields() print (layer.fields().names())
Output:
['PARK_NAME', 'PARK_ID', 'PARK_URL', 'AREA_HEC', 'Length']
Adding/Updating Field's Attributes
We already had a new field Length, but there is no attribute value in it, still empty. Next let's calculate the boundary length and add it to each feature.To add or updating attribute value the changeAttributeValues method is used from data provider class. To calculate the boundary length can be done using the length method from QgsGeometry class. The attribute's value is defined in a dict data type with the key is field's index to be updated (in this case Length with has index 4) and the value of the respective boundary length.
#UPDATING/ADD ATTRIBUTE VALUE layer.startEditing() for f in features: id=f.id() length=f.geometry().length() attr_value={4:length} layer_provider.changeAttributeValues({id:attr_value}) layer.commitChanges()
Add the layer into QGIS map canvas and open the attribute table. Can be seen as in figure 1 the new field Length and the length values has been added to each feature.
Figure 1. Updating attribute value of Length Field |
Deleting Field(s)
To delete a field, simply can be used deleteAttributes method from data provider class. The method required a list that contains field index to be deleted. For example we want to delete the Length field that already added before which has index 4. When done, don't forget to call updateFields method to make the change take in place.#DELETE FIELD layer_provider.deleteAttributes([4]) layer.updateFields()
That's all the tutorial how to work with vector layer, in particular how to add, delete and updating field's value. To learn more about QGIS Python programming. Visit QGIS Python Programming Series that offer other interesting topics.