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?
1 Answer 1
You could use something like the following which:
- Joins your shapefiles using
QgsVectorJoinInfo()
- Updates the address field
- 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") ThanksJamieTasker– JamieTasker2017年01月04日 15:37:58 +00:00Commented Jan 4, 2017 at 15:37
-
@JamieTasker - Most welcome! You defined the layers but did you load them using
QgsMapLayerRegistry.instance().addMapLayers([layer1, layer2])
?Joseph– Joseph2017年01月04日 15:41:36 +00:00Commented Jan 4, 2017 at 15:41 -
1Excellent, that's exactly what I was after! Thanks ever so much for your help!JamieTasker– JamieTasker2017年01月04日 15:54:21 +00:00Commented Jan 4, 2017 at 15:54
-
@JamieTasker - Glad it was helpful ;)Joseph– Joseph2017年01月04日 15:56:23 +00:00Commented 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():grego– grego2021年10月27日 23:25:42 +00:00Commented Oct 27, 2021 at 23:25