For a QGIS 2.0/2.2 and Python 2.7 plugin, I am trying to update one layer's field attribute with another layer's field attribute based on geometry function QgsGeometry.intersects(). My first layer is a point layer, the second layer is a buffer of a vector polyline layer containing azimuth measurements. I would like to update the point layer to include azimuth information of the buffer polygon it intersects (essentially a spatial join). It is to automatize the process described here. Currently, only the first feature in my points layer's bearing field is updated after committing changes (i expected all features to be updated).

rotateBUFF = my buffer polygon layer
pointLayer = my point layer to obtain azimuth data

rotate_IDX = rotateBUFF.fieldNameIndex('bearing')
point_IDX = pointLayer.fieldNameIndex('bearing')
rotate_pr = rotateBUFF.dataProvider()
point_pr = pointLayer.dataProvider()
rotate_caps = rotate_pr.capabilities()
point_caps = point_pr.capabilities()
pointFeatures = pointLayer.getFeatures()
rotateFeatures = rotateBUFF.getFeatures()

for rotatefeat in rotateFeatures:
    for pointfeat in pointFeatures:
        if pointfeat.geometry().intersects(rotatefeat.geometry()) == True:
            pointID = pointfeat.id()
            if point_caps & QgsVectorDataProvider.ChangeAttributeValues:
                bearing = rotatefeat.attributes()[rotate_IDX]
                attrs = {point_IDX : bearing}
                point_pr.changeAttributesValues({pointID : attrs})
有帮助吗?

解决方案

moving the iterator to the loop would do the trick:

for rotatefeat in rotateBUFF.getFeatures():
  for pointfeat in pointLayer.getFeatures():

Also, you don't need to commit changes if you work on the data provider. There are 2 ways to edit data:

  1. on the layer using its edit buffer, but you must enable the editing first. Once editing is finished, you must commit the changes.
  2. on the data provider as you need. No need to commit changes, they are applied directly when using changeAttributeValues.

Usually, it is recommended to edit on the layer to prevent modifications on layers which are not in edit mode. This is particularly true for plugins. But, if this code is strictly for you, it might be easier to work with the data provider. One advantage for the edit buffer is that you can commit changes at once, and if something went wrong during the loop, discard the changes.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top