4

I am trying to update an existing field on a shapefile using data from another shapefile. Basically, each attribute table contains an ID field that I want to use to update a field called "address".

So far, I have tried to use the processing alg "qgis:joinattributestable" and QgsVectorJoinInfo(). Both of these solutions however seem to create temporary join fields that are of no use to me.

Is this something that is possible with QGIS?

3

You could use something like the following which:

  1. Joins your shapefiles using QgsVectorJoinInfo()
  2. Updates the address field
  3. Removes the join

# Change names to match your layer names
layer_1_name = str("layer_1")
layer_2_name = str("layer_2")

for layer in QgsMapLayerRegistry.instance().mapLayers().values():
    if layer.name() == layer_1_name:
        qgis.utils.iface.setActiveLayer(layer)
        layer_1 = qgis.utils.iface.activeLayer()    
    if layer.name() == layer_2_name:
        qgis.utils.iface.setActiveLayer(layer)
        layer_2 = qgis.utils.iface.activeLayer()

# Set up join parameters            
layer_1_Field='ID'
layer_2_Field='ID'
joinObject = QgsVectorJoinInfo()
joinObject.joinLayerId = layer_2.id()
joinObject.joinFieldName = layer_2_Field
joinObject.targetFieldName = layer_1_Field
joinObject.memoryCache = True
layer_1.addJoin(joinObject)

# Define original field and joined field to update
original_field = layer_1.fieldNameIndex('address') 
joined_field = layer_1.fieldNameIndex(layer_2_name + '_address')

layer_1.startEditing()
for feat in layer_1.getFeatures():
    layer_1.changeAttributeValue(feat.id(), original_field, feat.attributes()[joined_field])

# Save the changes
layer_1.commitChanges()

# Remove join 
layer_1.removeJoin(layer_2.id())

The code was adapted from an earlier answer.

  • Thanks a bunch for that, worked without a hitch. Is there a way to get it to work using layers opened with 'QgsVectorLayer()'? I've tried to assign my layers as follows but the join does not seem to work: ' Layer 1 = QgsVectorLayer("path", "name". "ogr) Layer 2 = QgsVectorLayer("path","name,"ogr") Thanks – JamieTasker Jan 4 '17 at 15:37
  • @JamieTasker - Most welcome! You defined the layers but did you load them using QgsMapLayerRegistry.instance().addMapLayers([layer1, layer2])? – Joseph Jan 4 '17 at 15:41
  • 1
    Excellent, that's exactly what I was after! Thanks ever so much for your help! – JamieTasker Jan 4 '17 at 15:54
  • @JamieTasker - Glad it was helpful ;) – Joseph Jan 4 '17 at 15:56

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.