Python: How to Loop Functions in QGIS

Header

Shortly after I spent hours in Processing figuring out how to map coordinates onto an image, someone mentioned that what I REALLY want to be using is QGIS.

QGIS is to ArcGIS as Blender is to Maya and Gimp is to Photoshop. It’s open-source. Completely free for us broke folks. And it speaks Python.

So by way of introduction, I’m going to walk through a few basic commands to get me going.

Add a Base Map

You may notice that upon opening QGIS, you will be faced with a completely blank screen. Don’t panic. You’ve just got to add in a map background.

Plugin

The Ireland QGIS User Group Blog actually posted the code to get ESRI’s ArcGIS Online World Imagery to make it really easy:

qgis.utils.iface.addRasterLayer("http://server.arcgisonline.com/arcgis/rest/services/ESRI_Imagery_World_2D/MapServer?f=json&pretty=true","raster")

Once that’s pasted in, hit return, and you should see this:

BaseMap

Add Some Data

Not so long ago, I posted a script to scrape Airbnb data into a csv file. I haven’t been checking Airbnb’s HTML to make sure it hasn’t gotten screwier since I wrote said scraper. Because I’m weird, but not that weird. I still have the last csv file I scraped, so I’m using that. I was going to upload it here, but apparently WordPress doesn’t support csv uploads (Why WordPress? Are csvs not good enough for you?? And what the heck is a .3g2? Why can I upload that?) for reasons I’m not clear on.

Anyway. Back on topic.

CSV

Under Layer, go to Add Layer, and click on Add Delimited Text Layer. Choose your file, make sure you don’t mix up your X and Y values (or your points may end up in Antarctica), and let it fly.

Zooming into your layer, you should see something like this:

CSVLoaded

Now we’ve got a something to work with.

Throw in Some Python

Say I wanted to buffer those locations. Digital Geography has an awesome tutorial on how to do this which I’m going to summarize here.

First, you have to import the processing library to get access to the fixeddistancebuffer function.

import processing

Now, to keep life easy, we’re going to assign the active layer to a variable called layer.

layer = iface.activeLayer()

Here’s the template for the actual function:

processing.runalg(“qgis:fixeddistancebuffer”, LayerToBuffer, Distance, Segment, Dissolve True/False,”C:/Filepath.shp“)

Since our active layer is stored in the variable layer–we can just type .name() and trust QGIS to fill in the name. For example:

processing.runalg("qgis:fixeddistancebuffer",layer.name(),0.1,10,False,"C:/Users/Desktop/TestBuffer.shp")

That will save your buffer geometry to a shape file called TestBuffer. If you’re following along at home, you may have noticed that no shapes appeared on the map as a result. Don’t start verbally abusing QGIS yet. There’s two more lines:

newLayer=QgsVectorLayer('C:/Users/Desktop/TestBuffer.shp', "Buffer Layer", "ogr")

That one actually LOADS the layer, which is important, and assigns it to a variable which can be used to add it to the Map Layer Registry.

QgsMapLayerRegistry.instance().addMapLayer(newlayer)

Presto. Buffer layer.

Run a Loop

Say you want multiple buffer layers at different distances. You can push the lines that create and load the shapefile into a while loop. Then assign the distance value to a variable that increases with each iteration. Like so:

x=.001
while x < .01:
fp="C:/Users/Desktop/Buffer" + str(x) +".shp"
processing.runalg("qgis:fixeddistancebuffer", layer.name(), x, 10, False, fp)
newlayer=QgsVectorLayer(fp, "Buffer Layer", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(newlayer)
x+=.001

You can even use the buffer distance as part of the file nameβ€”if you convert the float value to a string using str().

The result should look something like this:

Yay.

Which you can then manipulate to get some animation going like the gif in my header or like this one.

Gif

More QGIS to come.

 

Advertisements
Tagged , , , , , ,

8 thoughts on “Python: How to Loop Functions in QGIS

  1. Greg Long says:

    I didn’t know about QGIS. Thanks πŸ˜€

    Liked by 1 person

  2. jhoga1956 says:

    Very good post I’ll have to give QGIS a try.

    Liked by 1 person

  3. howtoinqgis says:

    Nice post (… and blog)! You may also have a look at one similar post I wrote about the buffering of vectors. Even if thought for the creation of buffer from fields (it could be easily adapted to your case), it explains how to get buffers without recurring to the processing library: in this way, the execution time of the whole process will be shorter, mainly when dealing with many features.

    Liked by 1 person

  4. Lucas says:

    Hey that’s really cool. How are you manipulating the buffers to create the .gif?

    Like

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 )

Google+ photo

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

Connecting to %s

%d bloggers like this: