Python y GRASS GIS
En esta notebook, nos vamos a introducir en el uso de GRASS GIS con Python, y no solo eso, sino que ejecutaremos GRASS con Python dentro de Google Colab conectado a una base de datos o grassdata
dentro de nuestro Google Drive.
Antes de empezar entonces y para ganar tiempo, conectemos nuestro drive e instalemos GRASS en Google Colab.
Chequeamos el path de instalación de GRASS.
Mientras, vamos a recorrer brevemente los principales paquetes/librerías de Python que son parte de GRASS y nos permiten ejcutar sus funciones, a la vez que podemos combinar las salidas con otras librerías más tradicionales de Python.
¿Por qué Jupyter Notebooks y cómo usarlas?
Las Jupyter Notebook son aplicaciones servidor-cliente que permiten que el código escrito en un documento de cuaderno sea editado y ejecutado a través de un navegador web. Pueden ejecutarse en un ordenador local (sin necesidad de acceso a Internet) o utilizarse para controlar cálculos en un servidor remoto al que se accede a través de Internet (véase la documentación).
Las Jupyter Notebooks pueden ser interactivas y permiten combinar código, texto explicativo y resultados computacionales en un único documento. En general, son:
- convenientes para el desarrollo inicial de código (prototipado)
- ideales para la segmentación de código, con la posibilidad de volver a ejecutar celdas
- capaces de almacenar valores de variables de celdas ya ejecutadas
La notebook puede guardarse como un script ejecutable de Python además del formato nativo .ipynb
, o exportarse a varios formatos de documentación como PDF o Sphinx RST con un bonito estilo.
Edición y uso interactivo
Editar una Jupyter Notebook es muy fácil: en el navegador web, puedes navegar entre celdas de texto o código utilizando el ratón o atajos de teclado (ver Menú > Ayuda > Atajos de teclado). Se pueden ejecutar pequeños fragmentos de código celda por celda, guardar la notebook en su estado actual, o modificar y recalcular celdas o devolverlas a su estado anterior. Además de las celdas de código ejecutables, se puede utilizar Markdown en las celdas de documentación para hacerlas presentables a los demás.
Paquetes de Python en GRASS
grass.script
El paquete grass.script o GRASS GIS Python Scripting Library provee funciones para llamar módulos de GRASS dentro de scripts o rutinas Python. Las funciones más comúnmente usadas incluyen:
run_command
: usada cuando la salida de los módulos es un raster o vector, no se espera una salida de tipo texto.read_command
: se utiliza cuando la salida de los módulos es de tipo texto.parse_command
: se utiliza con módulos cuya salida puede convertirse en pareskey=value
o diccionarios.write_command
: se utiliza con módulos que esperan una entrada de texto, ya sea en forma de archivo o desde stdin.
Este paquete también proporciona varias funciones de wrapping para módulos de uso muy frecuente en GRASS, por ejemplo:
- Para obtener información de un raster, se utiliza script.raster.raster_info():
gs.raster_info('elevation')
- Para obtener información de un vector, se utiliza script.vector.vector_info():
gs.vector_info('roadsmajor')
- Para listar mapas de diferente tipo en un mapset, se utiliza script.core.list_grouped():
gs.list_grouped(type=['raster'])
- Para obtener la región computacional, se utiliza script.core.region():
gs.region()
Para más detalles, ver la documentación del paquete en: https://grass.osgeo.org/grass-stable/manuals/libpython/script_intro.html
grass.jupyter
La librería grass.jupyter mejora la integración de GRASS y Jupyter, y proporciona diferentes clases para facilitar la visualización de mapas de GRASS en el entorno Jupyter. Este paquete fue desarrollado por Haedrich et al. (2023) como parte de su proyecto para Google Summer of Code y con una student grant de GRASS.
Las classes más importantes son:
init
: inicia una sesión de GRASS y configura todas las variables de entorno necesarias para ejecutar GRASS desde Python y dentro de una Notebook.Map
: renderiza mapas 2DMap3D
: renderiza mapas 3DInteractiveMap
: permite la visualización interactiva utilizando la libreríafolium
TimeSeriesMap
: permite la visualización de datos espacio-temporales
Para más detalles, ver la documentación del paquete en: https://grass.osgeo.org/grass-stable/manuals/libpython/grass.jupyter.html
grass.pygrass
PyGRASS es una interfaz de programación de aplicaciones (API) de Python orientada a objetos para GRASS GIS desarrollada por Zambelli et al. (2013). PyGRASS ofrece interfaces a los módulos y funcionalidades de GRASS, así como a los datos vectoriales y ráster, de modo que permite acceder a cada minima unidad y desarrollar nuevos módulos con funciones de más bajo nivel. PyGRASS mejora la integración entre GRASS GIS y Python, haciendo el uso de Python bajo GRASS más consistente con el lenguaje mismo. Además, simplifica el scripting y la programación de GRASS y lo hace más natural para el usuario.
Dentro de esta librería, vamos a usar especialmente grass.pygrass.modules.shorcuts
que nos permite llamar a los módulos o funciones de GRASS de forma muy parecida a cómo lo haríamos en la consola de GRASS.
Para más detalles, ver la documentación del paquete en: https://grass.osgeo.org/grass-stable/manuals/libpython/pygrass_index.html
Otras librerías Python en GRASS GIS
Temporal framework
El GRASS GIS Temporal Framework implementa la funcionalidad SIG temporal de GRASS GIS y proporciona una API para implementar módulos de procesamiento espacio-temporal. El framework introduce conjuntos de datos espacio-temporales que representan series temporales de mapas raster, raster 3D o vectoriales. Este marco proporciona las siguientes funcionalidades:
- Asignación de marcas de tiempo a mapas y registro de mapas en la base de datos temporal
- Modificación de marcas de tiempo
- Creación, cambio de nombre y supresión de conjuntos de datos espacio-temporales
- Registro y anulación del registro de mapas en conjuntos de datos espacio-temporales
- Consulta de mapas registrados en conjuntos de datos espacio-temporales mediante SQL
- Análisis de la topología espacio-temporal de los conjuntos de datos espacio-temporales
- Muestreo de conjuntos de datos espacio-temporales
- Cálculo de las relaciones temporales y espaciales entre los mapas registrados
- Funciones de nivel superior compartidas entre módulos
Para más detalles, ver la documentación de la librería en: https://grass.osgeo.org/grass-stable/manuals/libpython/temporal_framework.html
Testing framework
El GRASS GIS Testing framework está basado en el paquete unittest
de Python con un gran número de mejoras, extensiones y cambios específicos ajustados a GRASS. Estos cambios incluyen la creación de reportes de pruebas HTML compatibles con GRASS, o la ejecución de pruebas de manera que las terminaciones de procesos potencialmente causadas por funciones de la librería C no influyan en el proceso principal de pruebas.
Algunas pruebas se ejecutarán sin ningún dato, pero muchas pruebas requieren la versión básica de los datos de muestra para Carolina del Norte.
Para más detalles, ver la documentación de la librería en: https://grass.osgeo.org/grass-stable/manuals/libpython/gunittest_testing.html
Ejemplos con cada paquete
Primero, iniciemos una sesión de GRASS GIS. Necesitamos definir la ruta hasta un mapset, por lo tanto vamos a usar los datos de muestra de GRASS, i.e., el sample dataset de North Carolina.
Ahora sí, estamos listos para importar los paquetes de GRASS e iniciar una sesión:
Notar que iniciamos sesión con gj.init()
. No obstante, también podríamos usar session = gs.setup.init("~/grassdata/nc_spm_08_grass7/PERMANENT")
.
Corroboramos que GRASS inició correctamente:
¿Qué versión de GRASS estamos ejecutando?
Ejemplos con grass.script
Listamos los mapas raster del mapset PERMANENT:
Obtenemos info de un mapa raster:
Ahora, hagamos lo mismo pero para los mapas de tipo vectorial.
Imprimimos la region computacional actual:
Cambiamos la región computacional al vector area_edificada_cba
:
Verificamos los atributos del vector seleccionado:
Extraemos el área urbana de Río Cuarto:
Listamos los vectores por un patrón:
Verificamos los atributos del nuevo vector creado:
y obtenemos información sobre el mismo. Notar que podemos seleccionar qué información queremos extraer, i.e., la salida es un diccionario.
Ejemplos con grass.jupyter
Ahora vamos a demostrar el uso de las dos clases más comunes del paquete grass.jupyter
para graficar mapas. Usamos primeramente la clase interactiva que nos permite mostrar nuestras salidas sobre mapas base como el de OpenStreetMap, por ejemplo.
A continuación, creamos una salida estática, utilizando la clase Map
. Esta salida es similar a utilizar el Map Display en la GUI y exportar el resultado.
Ejemplos con grass.pygrass
Finalmente, vamos a ejemplificar el uso de la interfaz modules
dentro de grass.pygrass
. Si bien esta interfaz nos permite ejecutar comandos de GRASS casi como si los ejecutásemos en la terminal, las salidas no están optimizadas para ser usadas como entrada para otros comandos. Para ello, es más conveniente usar grass.script
o funciones de más bajo nivel de grass.pygrass
que permiten acceder a los componentes básicos de los objetos dentro de GRASS.