I'm writing code that add some attributes. I need create an attribute, 'AREA_HA', and to calculate the area in HA. My code works well, but doesn't create the attribute 'AREA_HA' and calculation produces no result. I looked at some answers here in stack, but none applied to the structure of my code. How I can improve it?
path = 'D:/shps/SHP'
for root, directory, files in os.walk(path):
for file in files:
if file.endswith('.shp'):
full_path = os.path.join(root,file)
vlayer = QgsVectorLayer(full_path,file[:-4],'ogr')
feats = vlayer.getFeatures()
for feat in feats:
geom = feat.geometry()
if geom.type() == QgsWkbTypes.PolygonGeometry:
vlayer.startEditing()
vlayer.addAttribute(QgsField('ID',QVariant.String, 'string',50))
vlayer.addAttribute(QgsField('STUDY',QVariant.String,'string',100))
vlayer.addAttribute(QgsField('PROJECT',QVariant.String,'string',100))
vlayer.addAttribute(QgsField('STAGE',QVariant.String,'string',100))
vlayer.addAttribute(QgsField('DATE',QVariant.String,'string',30))
vlayer.addAttribute(QgsField('COMPANY',QVariant.String,'string',50))
expression = '($area/10000)'
field = QgsField('AREA_HA', QVariant.Double, 'double',19)
vlayer.addExpressionField(expression, field)
vlayer.commitChanges()
print(vlayer)
Best Answer
You have a number of issues here. Firstly, with the
addExpressionField()
method, you are trying to add a virtual field to aQgsVectorLayer
object which is not loaded into a project, which simply won't work. Virtual fields are added to the end of an attribute table in a project vector layer and exist only in the project settings in which they have been created. They cannot be permanently added to the layer's data provider. Please see the first point under the Note section here.Other than that you have some logic errors e.g. you are adding fields to the layer for every feature, so you should move that section out of the feature iterator loop. Also you need to call
updateFields()
after adding the fields.I strongly recommend studying the PyQGIS Developer Cookbook, especially the following sections:
Modifying Vector Layers
Expressions with features
Try the following script: