5

I have a vector layer, populated with points, and I want to programmatically add to this layer.

The part related to the geometry works just out of the box, but I was having trouble with adding attribute values to the new features. The problem is, when I add a new feature to the layer, I do not manage to specify fields. The feature would complain on exceptions.KeyError.

        featureList = []
        ## now add the computed points to the layer
        for p in [p for p in points.values() if p['computed']]:
            x, y = p['coordinates']
            feature = QgsFeature()
            layerPoint = transf.transform(QgsPoint(x, y))
            feature.setGeometry(QgsGeometry.fromPoint(layerPoint))
            feature['id'] = p['id']
            featureList.append(feature)

        layer.dataProvider().addFeatures(featureList)
        layer.commitChanges()

And before you ask, obviously I'm sure it's the feature['id'] which is giving trouble, not the p['id'].

So the short version of the question was "how do I specify fields of a feature before it was ever part of a layer?"

5

The first answer I found amounted to copying the fields from an existing feature from the same layer, and feed them to the new feature. It works fine for me, because the code needs at least 3 features to do anything useful, and because earlier in the code I was looping over the features in the layer:

for feature in layer.getFeatures():
    # this is a loop I needed anyway
    .
    .
    .
    pass
# copy the fields definition from an existing feature
fields = feature.fields()

I am very new to programming in QGIS so I had not yet even seen the page that underdark is linking to in her answer. And even if her answer does not hit the point, the link does help.

I don't need to copy the fields from an existing feature, I can grab them directly from the layer.

fields = layer.fields()
featureList = []
for p in [p for p in points.values() if p['computed']]:
    x, y = p['coordinates']
    feature = QgsFeature()
    # inform the feature of its fields
    feature.setFields(fields)
    layerPoint = transf.transform(QgsPoint(x, y))
    feature.setGeometry(QgsGeometry.fromPoint(layerPoint))
    feature['id'] = p['id']  # this now works
    featureList.append(feature)
2

The method you're missing is QgsFeature.setAttributes(). This works for any newly created feature

# add a feature
fet = QgsFeature()
fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10,10)))
fet.setAttributes(["Johny", 2, 0.3])
pr.addFeatures([fet])

Source: http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/vector.html

  • I don't see how I know which attribute I am setting with fet.setAttributes(["Johny", 2, 0.3]). My code needs to work with a layer which it did not create, so I cannot assume any ordering nor type details in attribute definition. – mariotomo Jan 9 '17 at 14:25
  • (according to google, the code snippet you are giving me has been used like 600 times) ;-) – mariotomo Jan 9 '17 at 14:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.