Unit 10 - Python intro

Python programming/scripting language is very popular in the field of GIS and a science in general. Python is also the main scripting platform for Esri products (see arcpy package). GRASS is not an exception. In reality, many GRASS modules are simple Python scripts, eg. r.mask (see Source Code section).

Important

GRASS GIS currently only works Python version 2! Python 3 support is currently under development. First GRASS GIS version with full Python 3 support will be probably 7.8.

GRASS Python environment includes various libraries, see GRASS documentation for details. We will focus on three main libraries related to this workshop:

PyGRASS has been originally design as an object-oriented Python API for GRASS GIS. This is a major difference to GRASS Scripting Library which consists of procedures - Python functions. It is important to mention that PyGRASS has not been designed as replacement of GRASS Scripting Library, the both libraries are living next to each other. It is up to the user (you) which library use in his/her scripts. It’s also possible to compine the both libraries in one script.

Let’s do our first steps towards Python scripting in GRASS GIS using Layer Manager’s Python tab.

../_images/layer-manager-python.png

Fig. 74 Python shell in Layer Manager.

As initial step we try to script simple computation workflow below:

  1. Set computation extent to Oslo region, align region to Sentinel bands
  2. Extend computation region by 1km offset
  3. Set mask based on cloud vector map
  4. Compute NDVI
  5. Compute NDVI values statistics, print min, max and mean NDVI values

It turns into bunch of GRASS commands (map names shorten):

# 1.
g.region vector=oslo align=B04_10m
# 2.
g.region n=n+1000 s=s-1000 e=e+1000 w=w-1000
# 3.
r.mask --overwrite -i vector=MaskFeature
# 4.
i.vi --overwrite red=B04_10m output=ndvi viname=ndvi nir=B08_10m
# 5.
r.univar map=ndvi

Tip

You can log GRASS modules run from Console and GUI dialogs into file by Log file (click to start/stop logging). Then you can use logged commands as a starting point for your first Python script.

../_images/layer-manager-log-file.svg

Fig. 75 Log GRASS commands into file.

We turn these commands into Python syntax. In this unit GRASS Scripting Library will be used since GUI Python tab already includes this library. Only basic syntax will be explained. In next units we will switch to more fancy PyGRASS environment.

GRASS commands can be run by core.run_command function.

# 1.
grass.run_command('g.region', vector='oslo', align='L2A_T32VNM_20170705T105031_B04_10m')
# 2.
grass.run_command('g.region', n='n+1000', s='s-1000', e='e+1000', w='w-1000')
# 3.
grass.run_command('r.mask', flags='i', vector='MaskFeature', overwrite=True)
# 4.
grass.run_command('i.vi', red='L2A_T32VNM_20170705T105031_B04_10m', output='ndvi',
                  viname='ndvi', nir='L2A_T32VNM_20170705T105031_B08_10m', overwrite=True)
# 5.
grass.run_command('r.univar', map='ndvi')

Note

Function core.run_command prints return code of run command, 0 for success.

Tip

Python shell has its history, you can browse previous commands by Alt+P, next commands by Alt+N.

There is a small problem with our first script. Output of module r.univar is discarded by core.run_command function, only return code is printed. A solution is to run r.univar by core.read_command which does not discard command output. Instead of return code, the output is returned by this function. But it is still not perfect, statistics is printed to standard output. It would be nice to manage command output as Python object, eg. a directory. To fulfill this requirement we need to change two issues:

  • run r.univar with -g to enable shell script (parse-able) output
  • use core.parse_command function which parses output and store result as Python directory object
# 5.
stats = grass.parse_command('r.univar', flags='g', map='ndvi')
print ('NDVI min value: {0:.4f}'.format(float(stats['min'])))
print ('NDVI max value: {0:.4f}'.format(float(stats['max'])))
print ('NDVI mean value: {0:.4f}'.format(float(stats['mean'])))
../_images/python-result.svg

Fig. 76 Running Python code in Layer Manager.

Resultant NDVI raster map can be displayed easily by calling AddLayer() function directly from Python shell.

AddLayer('ndvi')

Graphical Modeler and Python

It is good to know that a model created in Graphical Modeler can be easily turned into Python script. Let’s open the one of models created in Unit 09 - Model tuning: ndvi-v2.gxm and go to Python editor tab.

Generated Python script can be easily modified in built-in simple editor.

../_images/model-python-editor.svg

Fig. 77 Python editor integrated in Graphical Modeler.