After getting accustomed with vector and raster layer basics, let’s get to a more advanced topic and see how we can use Processing in PyQGIS to perform different spatial analysis tasks.

If you’ve ever looked into the Processing history (Processing | History), you may have noticed that it keeps records of all the Processing tools you’ve executed from the toolbox, including the corresponding code snippet starting with processing.run. We can copy this code to use it in the Python console. For example, this will run the native buffer algorithm (data from NaturalEarthData):

uri = "E:/Geodata/NaturalEarth/natural_earth_vector.gpkg|layername=ne_110m_populated_places"
result = processing.run("native:buffer", 
    {'INPUT':uri,'DISTANCE':10,'SEGMENTS':5,'END_CAP_STYLE':0,'JOIN_STYLE':0,'MITER_LIMIT':2,
    'DISSOLVE':False,'OUTPUT':'memory:'})

So far, this does not yet load the results. The resulting vector layer can be accessed using result['OUTPUT']. To add it to the current project, we use:

QgsProject.instance().addMapLayer(result['OUTPUT'])

This is the first time we use QgsProject.instance() to access the current QGIS project object. This object has many useful functions, including adding and removing map layers.

Let’s take a step back and examine the code! processing.run takes two parameters: the first is the algorithm name. The second parameter are algorithm settings in curly brackets {}. So far, we have only used curly brackets for string formatting. Here, we use them to create an input parameter dictionary for the processing algorithm. Let’s have a closer look at the dictionary (dict for short) with some added line breaks for readability:

{'INPUT':uri,
 'DISTANCE':10,
 'SEGMENTS':5,
 'END_CAP_STYLE':0,
 'JOIN_STYLE':0,
 'MITER_LIMIT':2,
 'DISSOLVE':False,
 'OUTPUT':'memory:'}

The dictionary has multiple items and each item consists of a key (e.g. ‘INPUT’) and a value (e.g. the uri variable). Therefore, items are often referred to as key-value pairs.

The input parameters are not the only dictionary in this example. The result returned by processing.run() is also a dictionary and it shows how we can access a specific item by providing the corresponding key using square brackets: result['OUTPUT']

A couple of items in the input dictionary are not too self-explanatory. What does 'JOIN_STYLE':0 mean, for example? To answer questions like this, we can use the algorithmHelp() function:

processing.algorithmHelp("native:buffer")

The help tells us that available values for the join style are 0: Round, 1: Miter, and 2: Bevel.

Instead of running the algorithm first and loading the results in a second step, there is also a convenience function called runAndLoadResults():

processing.runAndLoadResults("native:buffer", 
    {'INPUT':uri,'DISTANCE':10,'SEGMENTS':5,'END_CAP_STYLE':0,'JOIN_STYLE':0,'MITER_LIMIT':2,
    'DISSOLVE':False,'OUTPUT':'memory:'})

These are the basics of using Processing algorithms in PyQGIS. You also saw how to create dictionaries and access dictionary items.

Next


PyQGIS 101 is a work in progress. I’d appreciate any feedback, particularly from beginners!

Advertisement
10 comments
  1. gustavo said:

    Me está gustando mucho este curso, gracias!! // I’m really enjoying this course, thanks!!
    gustavo!!

  2. Kevin Osborne said:

    I like the 101 concept, its proving very useful. This piece on running algorithms also helps with understanding. Could you possibly expand it to show how to use algorithms and their outputs from other providers?
    e.g. Grass v.distance, as the output is a string and needs to be handled differently.. thats one Im stuck on specifically

  3. Laura said:

    I’ve tried to save the output, by using a variabele “bewaard”. But instead of saving a layer, I saw a saved Geopackage named “bewaard.gpkg” in de root directory!!

    pand =”…path to pand.shp …”
    BIZ= “…path to BIZ.shp .”
    bewaard=”:path to testoutput ….extractbylocation.shp”
    processing.run(“native:extractbylocation”, {‘INPUT’:pand,’PREDICATE’:[6],’INTERSECT’:BIZ,’OUTPUT’:’bewaard’ })

    And I see this in the console:
    processing.run(“native:extractbylocation”, {‘INPUT’:pand,’PREDICATE’:[6],’INTERSECT’:BIZ,’OUTPUT’:’bewaard’ })
    {‘OUTPUT’: ‘bewaard.gpkg’}

    Thats surprising! My question is do I use this command to save the vecorlayer to my directory?:

    # Write to an ESRI Shapefile format dataset using UTF-8 text encoding
    bewaard = QgsVectorFileWriter.writeAsVectorFormat(layer,
    “/path/to/folder/my_esridata”,
    “UTF-8″,
    driverName=”ESRI Shapefile”)

    • Laura said:

      I think I found the answer, this wil do it:

      ‘OUTPUT’:’bewaard.shp’

  4. Laura said:

    Hi Anita,

    I try to practise a few days a week, So far so good! Now I will make a processing script with join. When I look in the history a few months ago, I see this:
    processing.run(“qgis:joinattributesbylocation”, {‘INPUT’:’/…….
    when I run the processingtool again I see in the history::
    processing.run(“native:joinattributesbylocation”, {‘INPUT’:……

    The “native” is added in the syntax! Could this happens because I ran the script last time in QGIS 3.12? Is it possible the syntax change somtimes?

    • Hi Laura,
      Yes, it is definitely possible that the syntax changes, particularly between major releases. I think QGIS 2 used qgis:algname while QGIS 3 uses native:algname.

  5. Immo said:

    Hi,

    I have trouble running line 5, line 3 works but line 5 prints: “Konnte Quelllayer für INPUT nicht laden: ungültiger Wert”, any idea ?

    1 layer1=’E:/QGIS/file1.gpkg|layername=layer1name’
    2 layer2=’E:/QGIS/file2.gpkg|layername=layer1name’

    3 #test = iface.addVectorLayer(layer1, “test”, “ogr”)

    4 # select from landuse>natural
    5 out1 = processing.run(‘native:extractbyexpression’, {‘INPUT’: layer1,’EXPRESSION’:
    ‘landuse=\’natural\”,’OUTPUT’:’memory:’})

    6 # calc landuse area
    7 out2 = processing.run(‘qgis:fieldcalculator’, {‘FIELD_LENGTH’: 10,’FIELD_NAME’: ‘area_natural’,’FIELD_PRECISION’:
    3,’FIELD_TYPE’: 0,’FORMULA’: ‘$area’,’INPUT’: out1,’NEW_FIELD’: True,’OUTPUT’:’memory:’})

  6. Bernie Connors said:

    At the bottom of each lesson it would be nice to include the title of the next lesson beside the “Next” link and perhaps a link to the list of lessons.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: