5

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?

PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Jan 4, 2017 at 12:52

1 Answer 1

5

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 .

answered Jan 4, 2017 at 13:05
5
  • 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 Commented Jan 4, 2017 at 15:37
  • @JamieTasker - Most welcome! You defined the layers but did you load them using QgsMapLayerRegistry.instance().addMapLayers([layer1, layer2])? Commented Jan 4, 2017 at 15:41
  • 1
    Excellent, that's exactly what I was after! Thanks ever so much for your help! Commented Jan 4, 2017 at 15:54
  • @JamieTasker - Glad it was helpful ;) Commented Jan 4, 2017 at 15:56
  • For anyone reading this using QGIS 3.x : QgsMapLayerRegistry is gone from QGIS 3.x; it's functionality has moved to QgsProject. So you would use: for layer in QgsProject.instance().mapLayers().values(): instead of for layer in QgsMapLayerRegistry.instance().mapLayers().values(): Commented Oct 27, 2021 at 23:25

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.