我正在尝试使用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