Setup QGIS in Google Colab

June 12, 2020 | category 👉 python, GIS, QGIS, pyqgis

Share on:

QGIS + Google Colab + Google Drive

png

Before we start make sure you have a Google account and you need to install Google Backup and Sync to make sure you can synchronize your google drive with your local computer. Create particular folder and organize your working data.

schema drive.jpg

Traditional GIS software would be installed and use from local PC or your laptop. Since there is a Google Colaboratory or Colab for short, it is now possible to process any geospatial data from anywhere as long as you have an Internet connection plus you have free access to GPUs!

Now you can even start this tutorial from anywhere even from your phone or tablet 💪😆

1. Setup

If you need latest or other version of qgis visit here

Since we will work in Linux environment, make sure you understand a bit about Linux terminal commands. If you are new to this you can visit this website.

!sudo apt-get install gnupg software-properties-common
!sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 51F523511C7028C3
!sudo add-apt-repository "deb https://qgis.org/debian-ltr/ `lsb_release -c -s` main"
!sudo apt-get update
!sudo apt-get install opencl-headers ocl-icd-opencl-dev
!sudo apt-get install qgis python3-qgis qgis-plugin-grass
!python -m pip install rasterio gdal
!python -m pip install geopandas

If there are no errors, then you can check the qgis processing plugins folder.

# Check processing folder
!ls -lh /usr/share/qgis/python/plugins/processing

2. Testing

We need to authorize your notebook to access your Google Drive.

# imports the drive library and mounts your Google Drive as a VM local drive
from google.colab import drive
drive.mount('/content/gdrive')

Symlink your folder from Google drive so we can access it from VM. In my case, my folder in Google Drive called misc_data and you need to change this folder to reflect your own then lets call our folder in VM environment as data.

#symlink dataset folder from Google Drive to local folder in Colab.
!ln -s /content/gdrive/My\ Drive/misc_data /content/data
# check your folder contents
!ls -sR /content/data

sample of my folder content in google drive:

# DONT COPY THIS TO COLAB
-/misc_data/
    -raster/
        - img.tif
    -geojson/
        - area.geojson
    -dem/
        - N04E115.tif

sample of my folder in Colab’s VM environment looks like this:

# DONT COPY THIS TO COLAB
-/data/
    -raster/
        - img.tif
    -geojson/
        - area.geojson
    -dem/
        - N04E115.tif

In order to run processing algorithms correctly, you need to append path to plugins so we can call Qgis algorithms from python environment.

# environment setup
!export PYTHONPATH="/usr/share/qgis/python"
!export LD_LIBRARY_PATH="/usr/lib/qgis"
!export QGIS_PREFIX="/usr"
%matplotlib inline
import os
from osgeo import ogr
from qgis.core import *
from qgis.analysis import *

import geopandas as gpd
import matplotlib.pyplot as plt
# If there an error, run it twice
import sys
sys.path.append('/usr/share/qgis/python/plugins') # path to qgis plugins
import processing
from processing.core.Processing import Processing

Processing.initialize()
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
# Check available QGIS processing algorithms
for alg in QgsApplication.processingRegistry().algorithms():
        print(alg.id(), "--->", alg.displayName())

2.1 Vector Processing

source = r"/content/data/geojson/area.geojson"
inputvector = QgsVectorLayer(source)
fig, ax = plt.subplots(figsize = (10,10))
gpd.read_file(source).plot(ax=ax);

png

vertice_out = r"/content/data/geojson/out_vertices.geojson"
# delete output if exist
if os.path.exists(vertice_out):
    os.remove(vertice_out)
else:
    pass
params = {
    'INPUT': inputvector,
    'OUTPUT': vertice_out
}
feedback = QgsProcessingFeedback()
processing.run("native:extractvertices", params, feedback=feedback)
fig, ax = plt.subplots(figsize = (10,10))
gpd.read_file(vertice_out).plot(ax=ax);

png

buf_out = r"/content/data/geojson/buffer_output.geojson"
# delete output if exist
if os.path.exists(buf_out):
    os.remove(buf_out)
else:
    pass
params = {
    'INPUT': inputvector,
    'DISTANCE': 500,
    'SEGMENTS': 50,
    'END_CAP_STYLE':0,
    'JOIN_STYLE':0,
    'MITER_LIMIT':2,
    'DISSOLVE': False,
    'OUTPUT': buf_out
}
feedback = QgsProcessingFeedback()
processing.run("native:buffer", params, feedback=feedback)
fig, ax = plt.subplots(figsize = (10,10))
gpd.read_file(buf_out).plot(ax=ax);

png

random_points = r"/content/data/geojson/random_points.geojson"
# delete output if exist
if os.path.exists(random_points):
    os.remove(random_points)
else:
    pass
params = {
    '-a': False,
    '-z': False,
    'GRASS_MIN_AREA_PARAMETER': 0.0001,
    'GRASS_OUTPUT_TYPE_PARAMETER': 0,
    'GRASS_REGION_PARAMETER': None,
    'GRASS_SNAP_TOLERANCE_PARAMETER': -1,
    'GRASS_VECTOR_DSCO': '',
    'GRASS_VECTOR_EXPORT_NOCAT': False,
    'GRASS_VECTOR_LCO': '',
    'column': 'z',
    'column_type': 0,
    'npoints': 2000,
    'restrict': inputvector,
    'seed': None,
    'where': '',
    'zmax': 0,
    'zmin': 0,
    'output': random_points
    }
feedback = QgsProcessingFeedback()
processing.run("grass7:v.random", params, feedback=feedback)
fig, ax = plt.subplots(figsize = (10,10))
gpd.read_file(random_points).plot(ax=ax);

png

2.2 Raster Processing

We will create a contour dataset using gdal:contour algorithm.

import rasterio
import rasterio.plot

rast_src = r"/content/data/dem/N04E115.tif"
with rasterio.open(rast_src) as src:
    fig, ax = plt.subplots(figsize = (10,10))
    rasterio.plot.show(src, ax=ax)

png SRTM Digital Elevation Model

from multiprocessing import Process

cont100 = r"/content/data/geojson/contour100m.gpkg"
# delete output if exist
if os.path.exists(cont100):
    os.remove(cont100)
else:
    pass
params = {
    'BAND': 1,
    'CREATE_3D': False,
    'EXTRA': '',
    'FIELD_NAME': 'ELEV',
    'IGNORE_NODATA': False,
    'INPUT': rast_src,
    'INTERVAL': 100,
    'NODATA': None,
    'OFFSET': 0,
    'OUTPUT': cont100
    }
feedback = QgsProcessingFeedback()
paralleled = Process(target=processing.run('gdal:contour', params, feedback=feedback))
paralleled.start()
paralleled.join()
fig, ax = plt.subplots(figsize = (10,10))
rasterio.plot.show(raster, ax=ax)
gpd.read_file(cont100).plot(ax=ax)

png Contour data generated using gdal:contour

UPDATE! View this Colab Notebook here

I hope this tutorial will be useful and enjoy your map processing while in commute as long as you keep your browser open.

⤎ back to posts