I have written a python script in QGIS which estimates the amount of residents for each building polygon by using census block data and building polygons (about 500 000 buildings in an area of about 900 km2).
The relevant data from the census blocks was merged to the building layer, so only the building layer is used in the script to collect the data. It has the following fields:
| A_building | id_census | pop_census_block |
The steps of the script are:
- Sort buildings by id_census
- Sum all building footprint areas for each census block
- Calculate the areal share and from that the amount of residents for each footprint.
- Update 2 attributes of the feature (
layer.updateFeature(feat[share, residents]))
The 3rd and 4th step happen in a loop, that iterates over each building polygon. This loop takes two days, which seems to me too long for such a simple operation. Is there a faster way to update the features of a layer, like sending the calculated data as a list?
Here is the relevant section in the script:
# feats is a python list:
feats = [feat for feat in layer.getFeatures(QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes(limit_cols))
]
# sort feats
feats.sort(key=itemgetter(col_census_id))
...
# Get unique census ids
census_ids = []
areas = dict()
for feat in feats:
census_id = feat[col_census_id]
if census_id not in census_ids:
census_ids.append(census_id)
areas[census_id] = 0
# Sum building area per census block
for i in range(len(feats)):
# Sum area
census_id = feats[i][col_census_id]
areas[census_id] += feats[i][col_bldg_area]
# Start an undo block
layer.beginEditCommand('Calculate share of area')
i, j, k = 0, 0, 0
layer.startEditing()
for feat in feats:
# Share of area
share = feat[col_bldg_area] / float(areas[feat[col_census_id]])
# Add share to feature
feat[col_share] = share
# Building population
feat[col_bldg_pop] = int(feat[col_pop] * feat[col_share])
layer.updateFeature(feat)
...
# End the undo block
layer.endEditCommand()
# Comit changes
layer.commitChanges()
return layer
layer.updateFeature()for each polygon takes a lot of time. Do you know how to do some kind of a multi update? – Alexander Gogl Jul 05 '16 at 14:07