<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 PyGRASS
PyGRASS is a library originally developed during the Google Summer of Code 2012. The PyGRASS library adds two main functionalities
Step1:  Create an instance of the vector map, with
Step2:  Open the map in write mode, with
Step3:  Create some vector geometry features, like two points
Step4:  Add the above two points to the new vector map with
Step5:  Finally close the vector map, with
Step6:  Now do the same thing using the context manager syntax provided by with, and creating and setting also the attribute table, with
Step7:  Note
Step8:  Working with raster data
A class with similar behaviour has been created for raster maps, import this class with
Step9:  Reading an existing raster map
Instanziate a raster class with
Step10:  Similar to the vector approach shown above, we can open a raster map with
Step11:  Now we have row by row access to the whole raster map. Below we show an example to access the first row
Step12:  Since row instances inherit from the numpy arrays, you can treat them as numpy arrays
Step15:  To convert the whole raster map to a numpy array, and then back to a GRASS GIS raster map, we can define two functions like
Step16:  Calling GRASS GIS modules
Import the Module class from the pygrass library, with
Step17:  Execute a GRASS GIS module with (here
Step18:  We can play with the python instance asking for inputs and outputs parameters and flags
Step19:  We can change the parameters values, parameterwise with
Step20:  Or re-execute the module passing only the parameter(s) that need(s) to be different
Step21:  We can retrieve the command string that will be execute in both bash and Python style
Step22:  Extra parameters of the Module class
run_
The run_ parameter defines if the module must be execute or not, the default value is True.
finish_
The finish_ parameter defines if the module has to wait the end of the process, default is True
env_
The env_ parameter defines the environmental variable that will be set and used by the process.
stdin_, stdout_, stderr_
The parameters stdin_, stdout_ and stderr_ are used to pass or capture the input or the output of the GRASS GIS modules.
Example
Step23:  Now we can call and capture the stdout of a GRASS GIS modules, with
<ASSISTANT_TASK:>
Python Code:
from grass.pygrass.vector import VectorTopo
from grass.pygrass.vector.geometry import Point
Explanation: PyGRASS
PyGRASS is a library originally developed during the Google Summer of Code 2012. The PyGRASS library adds two main functionalities:
a Python interface through the ctypes binding of the C API of GRASS, to read and write natively GRASS GIS 7 data structures.
a GRASS GIS module interface using objects to check the parameters and execute the respective modules.
For further discussion about the implementation ideas and performance are presented in the article:
Zambelli, P.; Gebbert, S.; Ciolli, M.   Pygrass: An Object Oriented Python Application Programming Interface (API) for Geographic Resources Analysis Support System (GRASS) Geographic Information System (GIS). ISPRS Int. J. Geo-Inf. 2013, 2, 201-219.
Playing with the C API of GRASS GIS through Python
Standard scripting with GRASS modules in Python may sometime seem discouraging especially when you have to do conceptually simple things like: iterate over vector features or raster rows/columns. With the standard scripting approach you would have to use several workaround such as:
- create temporary files,
- read and parse these files,
- work with the data,
- and remove all unnecessary files that were created by the script.
Most of GRASS GIS is written in C programming language. Using the C API, all this is much more simple since you can directly work on GRASS GIS data and do just what you need to do. However, you perhaps want to stick to Python. Here, the PyGRASS library introduced several objects that allow to interact directly with the data using the underlying C API of GRASS GIS.
Three main areas are covered so far:
- vector maps,
- raster maps,
- mapsets, and region.
Working with vector data
Creating a new vector map
Import the necessary classes:
End of explanation
view_points = VectorTopo('view_points')
Explanation: Create an instance of the vector map, with:
End of explanation
view_points.open(mode='w')
Explanation: Open the map in write mode, with:
End of explanation
point1 = Point(635818.8, 221342.4)
point2 = Point(633627.7, 227050.2)
Explanation: Create some vector geometry features, like two points:
End of explanation
view_points.write(point1)
view_points.write(point2)
Explanation: Add the above two points to the new vector map with:
End of explanation
view_points.close()
Explanation: Finally close the vector map, with:
End of explanation
# 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()
Explanation: Now do the same thing using the context manager syntax provided by with, and creating and setting also the attribute table, with:
End of explanation
with VectorTopo('view_points', mode='r') as points:
    for point in points:
        print(point, point.attrs['name'])
Explanation: Note: we don't need to close the vector map because it is already closed by the context manager.
Reading an existing vector map
End of explanation
from grass.pygrass.raster import RasterRow
Explanation: Working with raster data
A class with similar behaviour has been created for raster maps, import this class with:
End of explanation
elev = RasterRow('elevation', mapset='PERMANENT')
Explanation: Reading an existing raster map
Instanziate a raster class with:
End of explanation
elev.open(mode='r')
Explanation: Similar to the vector approach shown above, we can open a raster map with:
End of explanation
row = elev[0]
row
Explanation: Now we have row by row access to the whole raster map. Below we show an example to access the first row:
End of explanation
row * 2
row.shape
Explanation: Since row instances inherit from the numpy arrays, you can treat them as numpy arrays:
End of explanation
import numpy as np
from grass.pygrass.raster.buffer import Buffer
from grass.pygrass.gis.region import Region
def raster2numpy(rastname, mapset=''):
    Return a numpy array from a raster map
    with RasterRow(rastname, mapset=mapset, mode='r') as rast:
        return np.array(rast)
def numpy2raster(array, mtype, rastname, overwrite=False):
    Save a numpy array to a raster map
    reg = Region()
    if (reg.rows, reg.cols) != array.shape:
        msg = "Region and array are different: %r != %r"
        raise TypeError(msg % ((reg.rows, reg.cols), array.shape))
    with RasterRow(rastname, mode='w', mtype=mtype, overwrite=overwrite) as new:
        newrow = Buffer((array.shape[1],), mtype=mtype)
        for row in array:
            newrow[:] = row[:]
            new.put_row(newrow)
elev = raster2numpy('elevation', mapset='PERMANENT')
elev
numpy2raster(elev * 2, mtype='FCELL', rastname='doubled_elev', overwrite=True)
# import a function to render the results
from render import view
from grass.pygrass.modules.shortcuts import raster as r
# set the colors of the input and output maps to a predefined elevation color table
r.colors(map='elevation@PERMANENT,doubled_elev', color='elevation')
view(['elevation@PERMANENT'])
view(['doubled_elev'])
Explanation: To convert the whole raster map to a numpy array, and then back to a GRASS GIS raster map, we can define two functions like:
End of explanation
from grass.pygrass.modules import Module
Explanation: Calling GRASS GIS modules
Import the Module class from the pygrass library, with:
End of explanation
viewshed = Module('r.viewshed', input='elevation', output='viewshed2', coordinates=(635818.8, 221342.4), flags='c', overwrite=True)
Explanation: Execute a GRASS GIS module with (here: viewshed calculation):
End of explanation
viewshed.inputs.input
viewshed.inputs.coordinates
viewshed.outputs.output
viewshed.flags.c
Explanation: We can play with the python instance asking for inputs and outputs parameters and flags
End of explanation
viewshed.inputs.coordinates = [(635825, 221350)]
Explanation: We can change the parameters values, parameterwise with:
End of explanation
viewshed(output='viewshed_newpoint')
Explanation: Or re-execute the module passing only the parameter(s) that need(s) to be different:
End of explanation
viewshed.get_bash()
viewshed.get_python()
Explanation: We can retrieve the command string that will be execute in both bash and Python style:
End of explanation
import subprocess as sub
# Another way to use the Module class objects is through the shortcuts
# import the shortcuts for the general modules
from grass.pygrass.modules.shortcuts import general as g
Explanation: Extra parameters of the Module class
run_
The run_ parameter defines if the module must be execute or not, the default value is True.
finish_
The finish_ parameter defines if the module has to wait the end of the process, default is True
env_
The env_ parameter defines the environmental variable that will be set and used by the process.
stdin_, stdout_, stderr_
The parameters stdin_, stdout_ and stderr_ are used to pass or capture the input or the output of the GRASS GIS modules.
Example
End of explanation
greg = g.region(flags='p', stdout_=sub.PIPE)
print(greg.outputs.stdout)
Explanation: Now we can call and capture the stdout of a GRASS GIS modules, with:
End of explanation
<END_TASK>