I have a layer made of a field with repeted string values ("building") and a field with float values ("flatssurface"). I'd like to write a script to do some arithmetic operations (like sum, max and min, etc.) on all the values in column B which are associated to same values in column A but it doesn't work.
BUILDING FLATSURF SUM (wanted result)
1 40.0 115 (i.e. 40+45+30 m^2)
1 45.0 115
1 30.0 115
2 200.0 300 (i.e. 200+100 m^2)
2 100.0 300
3 60.0 140 (i.e. 60+80 m^2)
3 80.0 140
building=layer.dataProvider().fieldNameIndex('BUILDING')
flatssurface=layer.dataProvider().fieldNameIndex('FLATSURF')
uniquevalues=layer.uniqueValues(building,limit=10000)
for uv in uniquevalues:
feat=layer.getFeatures()
for f in feat:
tot=sum([flatssurface])
print tot
however it returns only the index of the field flats' surface (f[1]). For simplicity, I neglected the part on adding the field but I just tried to print the results, in order to check if it worked. If possible, I don't need answers related to GroupStats (Calculating sum of parts of column based on another column using QGIS Field Calculator?) or SQL or statistics (https://gis.stackexchange.com/editing-help) but I am looking only for solution related to Python.
Answer
when you do
flatssurface=layer.dataProvider().fieldNameIndex('FLATSURF')
you are indeeded getting the index (column number) of the field Flatsurf
. To access the data, in your loop, you need to get the feature, its attributes, and at last restrict to the proper column using the index you have found. So, the numerical value you want to use in your loop is
f.attributes()[flatssurface]
On top of accessing the field value, you need to sum it by building. Using your sample code you are making the cross product of all buildings by all building values.
buildingidx=layer.dataProvider().fieldNameIndex('BUILDING')
flatssurfaceidx=layer.dataProvider().fieldNameIndex('FLATSURF')
uniquevalues=layer.uniqueValues(buildingidx,limit=10000)
for uv in uniquevalues:
#re-initialise the total area for each building
tot = 0.0
#statement for selecting just the proper buildings
exp = QgsExpression('BUILDING = ' + str(uv))
request = QgsFeatureRequest(exp)
#Select only the buildings having the specified value
feat=layer.getFeatures(request)
#Do the sum
for f in feat:
tot+=f.attributes()[flatssurfaceidx]
#once done, print the building value and the corresponding total surface
print("Building:",uv, "Total surface:", tot)
No comments:
Post a Comment