我正在尝试使用QGIS Python插件编辑图层中每个要素的属性值。我发现在编辑模式之外执行此操作比在编辑时(甚至包括提交编辑)要慢得多。请参见下面的代码(在循环的同一点可互换的行)。我的样本数据集的速度差异为2秒(编辑模式)与72秒(非编辑模式)。
在编辑模式下修改属性:
layer.changeAttributeValue(feature.id(), 17, QtCore.QVariant(value))
在编辑模式之外修改属性:
layer.dataProvider().changeAttributeValues({ feature.id() : { 17 : QtCore.QVariant(value) } })
这是预期的行为吗?我不需要用户能够撤消更改,所以我认为我不需要使用编辑模式。
编辑1:请参阅下面的完整代码,包括两个版本(但已注释掉):
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)
两种方法产生的结果相同,但是通过数据提供程序进行写入需要更长的时间。该函数使用预先创建的缓冲区(棕褐色)对建筑物要素与附近区域(紫色)的接近程度进行分类。
1
那似乎不对。您可以共享更多代码了吗?
—
内森·W
@NathanW我已经添加了完整的功能。这个想法是检查两层的相交,然后在找到相交时用另一层的属性更新一层。
—
Snorfalorpagus
您正在使用哪种数据类型?
—
内森·W
这两层都包含一个ESRI Shapefile(多边形)。layer_target具有905个要素(建筑物),layer_buffered具有1155个要素(开放空间),这些多边形具有代表不同缓冲区(100m,50m,20m,10m,5m)的重叠多边形,因此具有'distance'属性。
—
Snorfalorpagus
您如何访问数据?(即通过网络,传统磁盘,SSD)?单个写入操作的I / O开销是否很耗时?作为测试:您是否可以尝试将所有更改的属性缓冲在内存中,然后最后一次调用dataProvider.changeAttributeValues()。
—
Matthias Kuhn