I am trying to modify attributes of features in QGIS comparing attributes with list'elements. First I define new attributes that need to be completed:
layer_intersected.dataProvider().addAttributes([QgsField("ID_acc",QVariant.Int,
QgsField("Nb_acc", QVariant.Int)])
layer_intersected.updateFields()
Then, I iterate over my features:
layer_intersected.startEditing()
for feature in layer_intersected.getFeatures():
I have two lists containing elements. Now, I want to test if the first attribute ("NOMBRE") is in one of the extracts of "list1" (the list is divided into a certain number of elements, each part of elements is an 'extract' of list) and if the second attribute ("nombre_2") is also in the same extract of "list2":
for i in xrange(0, len(list1), len(list_streets_network)):
l_streets_t1 = list1[i:i+len(list_streets_network)]
set_l_streets_t1 = set(list1[i:i+len(list_streets_network)])
set_l_streets_t2 = set(list2[i:i+len(list_streets_network)])
l_id = list_id_acc[i:i+len(list_streets_network)]
l_acc = list_nb_acc[i:i+len(list_streets_network)]
if feature["NOMBRE"] in set_l_streets_t1 and feature["nombre_2"] in set_l_streets_t2:
Then, if it is the case, I complete the attributes created
index1 = l_streets_t1.index(feature["NOMBRE"])
feature["ID_acc"] = l_id[index1]
feature["Nb_acc"] = l_acc[index1]
layer_intersected.updateFeature(feature)
Finally:
layer_intersected.commitChanges()
return layer_intersected
My problem is the speed of this code. I have to do this for thousands of features, and it takes days to calculate... I am sure there is a faster solution, but I do not know how to improve it...
I had a look on Numpy doc, but did not find the best solution... If someone has an idea, please help me ! :).
Here is the full code of the function:
> def create_id_for_right_matches(layer_intersected, list1, list2, list_id_acc, list_nb_acc, list_streets_network):
layer_intersected.dataProvider().addAttributes([QgsField("ID_acc", QVariant.Int), QgsField("Nb_acc", QVariant.Int)])
layer_intersected.updateFields()
layer_intersected.startEditing()
request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes(['NOMBRE', 'nombre_2'], layer_intersected.fields())
for feature in layer_intersected.getFeatures(request):
for i in xrange(0, len(list1), len(list_streets_network)):
l_streets_t1 = list1[i:i+len(list_streets_network)]
set_l_streets_t1 = set(list1[i:i+len(list_streets_network)])
set_l_streets_t2 = set(list2[i:i+len(list_streets_network)])
l_id = list_id_acc[i:i+len(list_streets_network)]
l_acc = list_nb_acc[i:i+len(list_streets_network)]
if feature["NOMBRE"] in set_l_streets_t1 and feature["nombre_2"] in set_l_streets_t2:
index1 = l_streets_t1.index(feature["NOMBRE"])
feature["ID_acc"] = l_id[index1]
feature["Nb_acc"] = l_acc[index1]
layer_intersected.updateFeature(feature)
layer_intersected.commitChanges()
return layer_intersected
layer_intersected.updateFeature(feature)
line. You don't need it and it's inefficient. 2) Here you can find tips to optimize yourgetFeatures()
call: nyalldawson.net/2016/10/speeding-up-your-pyqgis-scriptslayer.changeAttributeValue(fid, fieldIndex, newValue)
(as indicated in the post I mentioned) instead offeature["ID_acc"] = l_id[index1]
because, I repeat,updateFeature(feature)
is inefficient.