qgis – How to Replicate ‘Join Attributes by Location’ using pyQGIS

attribute-joinspyqgisqgisqgis-processingspatial-join

I would like to replicate the behaviour of the "Join Attributes by Location" function of the Qgis GUI (Vector >> Data Management Tools >> Join Attributes by Location) using a pyQgis script. I attempt this with the following call:

processing.runalg("qgis:joinattributesbylocation",
                  "path/to/points.shp", 
                  "path/to/polygons.shp",
                  u'intersects',
                  0,
                  0,
                  '',
                  1,
                  "path/to/output.shp")

This works except that the resulting output.shp does not contain all the fields of points.shp, it contains only the first two, which happen to be longitude and latitude.

When I use the GUI operation, the resulting output.shp retains all the fields of points.shp and polygons.shp. How do I ensure that all fields of the target vector appear in the output vector?

Best Answer

processing.runalg() can be called with only two arguments: a string indicating which algorithm to be used, e.g. "qgis:joinattributesbylocation", and a python dictionary object indicating parameter values which should not default, e.g. {PARAMETER_KEY:parameter_value}. Parameters left out of the dictionary fall back on their default values. Use the parameter names as presented in processing.alghelp() as keys.

To use the default behaviour, as the GUI Qgis call does, simply use default values. The complete call could be

processing.runalg("qgis:joinattributesbylocation",{
                        "TARGET":"path/to/points.shp", 
                        "JOIN":"path/to/polygons.shp", 
                        "OUTPUT":"path/to/output.shp"})

However, most processing algorithms have parameters that must be given. In that case, Qgis will present a warning such as:

Error: Missing parameter value for parameter PARAMETER_KEY

Using trial and error, can figure out which parameters are included in the minimum requirement. In this case, the complete call is:

processing.runalg("qgis:joinattributesbylocation",{
                        "TARGET":"path/to/points.shp", 
                        "JOIN":"path/to/polygons.shp",
                        "PREDICATE":u'intersects',
                        "SUMMARY":0,
                        "KEEP":1,
                        "OUTPUT":"path/to/output.shp"})
Related Question