Ich versuche, den Wert eines Attributs für jedes Feature in einer Ebene mithilfe eines QGIS Python-Plugins zu bearbeiten. Ich habe festgestellt, dass dies außerhalb des Bearbeitungsmodus viel langsamer ist als beim Bearbeiten (einschließlich des Festschreibens der Änderungen). Siehe Code unten (Linien, die an derselben Stelle in einer Schleife austauschbar sind). Der Geschwindigkeitsunterschied für meinen Beispieldatensatz beträgt 2 Sekunden (Bearbeitungsmodus) gegenüber 72 Sekunden (kein Bearbeitungsmodus).
Ändern eines Attributs im Bearbeitungsmodus:
layer.changeAttributeValue(feature.id(), 17, QtCore.QVariant(value))
Ändern eines Attributs außerhalb des Bearbeitungsmodus:
layer.dataProvider().changeAttributeValues({ feature.id() : { 17 : QtCore.QVariant(value) } })
Ist das ein erwartetes Verhalten? Der Benutzer muss die Änderungen nicht rückgängig machen können, daher muss ich den Bearbeitungsmodus nicht verwenden.
Bearbeiten 1: Siehe vollständigen Code unten mit beiden Versionen enthalten (aber auskommentiert):
def run(self):
try:
# create spatial index of buffered layer
index = QgsSpatialIndex()
self.layer_buffered.select()
for feature in self.layer_buffered:
index.insertFeature(feature)
# enable editing
#was_editing = self.layer_target.isEditable()
#if was_editing is False:
# self.layer_target.startEditing()
# check intersections
self.layer_target.select()
self.feature_count = self.layer_target.featureCount()
for feature in self.layer_target:
distance_min = None
fids = index.intersects(feature.geometry().boundingBox())
for fid in fids:
# feature's bounding box and buffer bounding box intersect
feature_buffered = QgsFeature()
self.layer_buffered.featureAtId(fid, feature_buffered)
if feature.geometry().intersects(feature_buffered.geometry()):
# feature intersects buffer
attrs = feature_buffered.attributeMap()
distance = attrs[0].toPyObject()
if distance_min is None or distance < distance_min:
distance_min = distance
if self.abort is True: break
if self.abort is True: break
# update feature's distance attribute
self.layer_target.dataProvider().changeAttributeValues({feature.id(): {self.field_index: QtCore.QVariant(distance_min)}})
#self.layer_target.changeAttributeValue(feature.id(), self.field_index, QtCore.QVariant(distance_min))
self.calculate_progress()
# disable editing
#if was_editing is False:
# self.layer_target.commitChanges()
except:
import traceback
self.error.emit(traceback.format_exc())
self.progress.emit(100)
self.finished.emit(self.abort)
Beide Methoden führen zum gleichen Ergebnis, das Schreiben über den Datenprovider dauert jedoch viel länger. Die Funktion klassifiziert die Nähe von Gebäudeelementen zu nahe gelegenen Feldern (lila) mithilfe vorgefertigter Puffer (braun).