Thursday 29 September 2016

pyqgis - Performing specific table joins in QGIS via python?


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?




Answer



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.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...