6

The following is currently unsuccessful at fulfilling a table field join to a point shapefile in QGIS.

All instances of the join object will print the proper values, and no error is flagged when processing - but the target layer does not exhibit any effect.

Something missing?

Heads = QgsVectorLayer(headCSV, 'Heads', 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(Heads)
self.iface.legendInterface().setLayerVisible(Heads,False)
grid = ftools_utils.getMapLayerByName(unicode('Grid'))
joinObject = QgsVectorJoinInfo()
joinObject.targetFieldName = str('ID')
joinObject.joinLayerID = Heads.id()
joinObject.joinFieldName = str('cellID')
grid.addJoin(joinObject)
grid.reload()

The following returns 'None'. I expect this is actually supposed to return the field names to be joined (e.g. - a clue to the mistake).

print joinObject.joinFieldNamesSubset()

Added the following, and now the previous update command returns the accurate fields to be joined - yet the destination layer does not show 'joined' fields...

joinObject.setJoinFieldNamesSubset(['someFieldName'])
Taras
  • 32,823
  • 4
  • 66
  • 137
Katalpa
  • 871
  • 10
  • 20

3 Answers3

9

This has worked for me:

# Get input (csv) and target (Shapefile) layers
shp=iface.activeLayer()
csv=iface.mapCanvas().layers()[0]

# Set properties for the join
shpField='code'
csvField='codigo'
joinObject = QgsVectorJoinInfo()
joinObject.joinLayerId = csv.id()
joinObject.joinFieldName = csvField
joinObject.targetFieldName = shpField
shp.addJoin(joinObject)

The error you are facing is, believe it or not, by a typo in joinLayerId. The question is, why QGIS doesn't throw an error there?

Germán Carrillo
  • 36,307
  • 5
  • 123
  • 178
5

If it's ok for you to use Processing algorithms for that, it's as simple as this (from the QGIS Python console):

import processing
res = processing.runalg("qgis:joinattributestable","/path/to/shape.shp","/path/to/table.csv","fieldShp","fieldTable","/path/to/output.shp")
layer = QgsVectorLayer(res['OUTPUT_LAYER'], "joined layer", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(layer)

You can have a look at the algorithm source code so that you decide whether you want to adapt it for your own script.

Germán Carrillo
  • 36,307
  • 5
  • 123
  • 178
  • While this is a great alternative, the need is a 'virtual join', as accomplished from the properties menu of a layer. This is because the operation might be done repeatedly, and avoidance of data overhead is a must. – Katalpa Feb 08 '15 at 13:51
  • Well, you could still use temporary layers setting the last parameter of the algorithm to None, but I see your point. – Germán Carrillo Feb 08 '15 at 14:48
0

Excellent example, I was very useful, combine a shp with a csv file, here my example performed:


import processing
res = processing.runalg("qgis:joinattributestable","d:/areas_geoestadisticas_estatales.shp","d:/poblacion.csv","cve_ent","cve_ent","d:/union_shp_csv.shp")
layer = QgsVectorLayer(res['OUTPUT_LAYER'], "Capa Unida", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(layer)

PolyGeo
  • 65,136
  • 29
  • 109
  • 338