This is an unmaintained course material, please see current material at:
Introduction to Python scripting in GRASS GIS 7
Python code can be executed in GRASS GIS GUI in the Python shell tab in the Layer Manager. You can enter any Python code, we can for example, do a simple calculation:import math
5 * math.sin(math.pi/2)
For this class, we will use more advanced method called IPython Notebook which gives us ability to write code, run code and also write nicely formated additional explanatory text and create a report or notes in this way.
To avoid installing IPython Notebook on all machines, we will use OSGeo Live machine from NCSU VLC in the class. Go to VLC reservation page and reserve machine called OSGeo Live. Wait for it to boot and you will get instructions how to connect to it using remote desktop method.
Once you are in OSGeo Live, start GRASS GIS from the menu at the bottom
left, submenu Geospatial, Desktop GIS. In GRASS GIS, go to the system
command line (not the one in GUI) and start ipython notebook
(note the space).
We are using North Carolina GRASS Location in this assignment. if you already have North Carolina GRASS GIS sample dataset or you are using OSGeo Live, you don't have to download anything.
Python Scripting Library
The GRASS GIS 7 Python Scripting Library provides functions to call GRASS modules within scripts as subprocesses. The most often used functions include:- run_command: most often used with modules which output raster/vector data where text output is not expected
- read_command: used when we are interested in text output
- parse_command: used with modules producing text output as key=value pair
- write_command: for modules expecting text input from either standard input or file
Calling GRASS GIS modules
We start by importing GRASS GIS Python Scripting Library:import grass.script as gscript
elevation.
gscript.run_command('g.region', raster='elevation')
run_command() function is the most commonly used one.
Here, we apply the focal operation average (r.neighbors) to smooth
the elevation raster layer. Note that the syntax is similar to bash syntax,
just the flags are specified in a parameter.
gscript.run_command('r.neighbors', input='elevation', output='elev_smoothed', method='average', flags='c')
Calling GRASS GIS modules with textual input or output
Textual output from modules can be captured using theread_command() function.
print(gscript.read_command('g.region', flags='p'))
print(gscript.read_command('r.univar', map='elev_smoothed', flags='g'))
parse_command() function automatically parses this output and returns a dictionary.
In this example, we call g.proj to display the projection parameters of the actual location.
gscript.parse_command('g.proj', flags='g')
read_command() function.
print(gscript.read_command('g.proj', flags='g'))
write_command() function we can conveniently pass
the string to the module. Here, we are creating a new vector with one point
with v.in.ascii. Note that stdin parameter is not used as a module parameter,
but its content is passed as standard input to the subprocess.
gscript.write_command('v.in.ascii', input='-', stdin='%s|%s' % (635818.8, 221342.4), output='view_point')
Convenient wrapper functions
Some modules have wrapper functions to simplify frequent tasks. We can obtain the information about the vector layer which we just created with the v.info wrapper.gscript.vector_info('view_point')
gscript.raster_what('elevation', [[635818.8, 221342.4], [635710, 221330]])
gscript.mapcalc("elev_strip = if(elevation > 100 && elevation < 125, elevation, null())")
print(gscript.read_command('r.univar', map='elev_strip', flags='g'))
region = gscript.region()
print region
# cell area in map units (in projected Locations)
region['nsres'] * region['ewres']
gscript.list_grouped(['raster'])
current_mapset = gscript.gisenv()['MAPSET']
gscript.list_pairs('raster', mapset=current_mapset)
PyGRASS
Standard scripting with GRASS modules in Python may sometime seem cumbersome especially when you have to do conceptually simple things like iterating over vector features or raster rows/columns. PyGRASS library introduced several objects that allow to interact directly with the data using the underlying C API of GRASS GIS.Working with vector data
Import the necessary classes:from grass.pygrass.vector import VectorTopo
from grass.pygrass.vector.geometry import Point
view_points = VectorTopo('view_points')
view_points.open(mode='w')
point1 = Point(635818.8, 221342.4)
point2 = Point(633627.7, 227050.2)
view_points.write(point1)
view_points.write(point2)
view_points.close()
# Define the columns of the new vector map
cols = [(u'cat',       'INTEGER PRIMARY KEY'),
        (u'name',      'TEXT')]
with VectorTopo('view_points', mode='w', tab_cols=cols, overwrite=True) as view_points:
    # save the point and the attribute
    view_points.write(point1, ('pub', ))
    view_points.write(point2, ('restaurant', ))
    # save the changes to the database
    view_points.table.conn.commit()
Reading an existing vector map:
with VectorTopo('view_points', mode='r') as points:
    for point in points:
        print(point, point.attrs['name'])
The above content is derived from workshop How to write a Python GRASS GIS 7 addon presented at FOSS4G Europe 2015. The relevant parts are: