Skip to Content

Nous adressons toutes nos pensées à la famille de notre ami Jérôme !

http://www.forumsig.org/showthread.php/43488-Disparition-de-Phoenix

GRASS GIS pour les experts: 1 - créer son propre module: r.in.rgb (importation directe d'un raster en couleur) en Python avec un menu pour le lancer

Niveau Expert
Logiciels utilisés GRASS GIS v.6.4.2
Plateforme Windows | Mac | Linux | FreeBSD

python

Les débutants avec GRASS GIS sont toujours perturbés par l'importation des couches de type raster qui donne pour résultat 3 couches (fichiers .red, .green et .blue) dans le cas de rasters multibandes.

J'ai montré dans GRASS GIS pas à pas pour les débutants: 3 - importer des couches matricielles (raster) et importance de la région comment régler le problème avec l'utilisation de r.composite et proposé un petit script pour automatiser ce processus (importation directe en couleur d'un fichier RGB), mais sans interface.

Or, ce serait beaucoup plus facile à utiliser avec une belle interface:

Comment faire en pratique?

La version 6.4.2 préfigure la future version 7 en permettant d'utiliser Python pour tout faire.

Construction du module r.in.rgb.py

Il s'agit en fait d'un seul script Python qui sera ici décomposé pour l'explication:

  • création de l'interface;
  • traitement.

Ensuite, nous verrons comment construire le menu pour exploiter le script:

Création de l'interface

L'interface de tous les modules de GRASS GIS repose sur des standards dont la plus belle explication se trouve dans Come scrivere uno script per grass (en italien, mais compréhensible). Ainsi l'interface montrée dans les figures est codée de la simple manière suivante:

#%module
#% description: Charge directement un raster couleur (RGB) (r.in.gdal + r.composite + g.delete)
#% keywords: raster
#%end
#%option
#% key: input
#% type: string
#% gisprompt: oldfile,file,dsn
#% answer: .
#% description: Fichier d'entrée
#% required : yes
#%end
#%option
#% key: output
#% type: string
#% gisprompt: oldraster,raster
#% description: nom de la couche raster de sortie
#% required : yes
#%end
#%flag
#%  key: o
#%  description: Override projection check
#%end
#%flag
#%end

dont les éléments sont très faciles à comprendre:

Options (Required)

Flags (optional)

le script Python

Le secret de la liaison entre les variables Python et les éléments de l'interface réside dans la commande grass.parser qui permet de récupérer le contenu des champs options et flags

options, flags = grass.parser()

Il y a 2 champs options:

  • input  qui est le champ destiné à  recueillir (à partir du bouton Browse) le chemin du fichier raster à traiter;
  • output qui est le champ où l'on indique le nom de la couche résultante dans GRASS;

Et un champ flags:

  • o qui permet de ne pas tenir compte de la projection du fichier  (c'est la projection du secteur (Location) qui prime).
entree = options['input']
sortie = options['output']
drap = flags['o']

Ensuite, on effectue la commande r.in.gdal avec les valeurs obtenues (sans tenir compte du drapeau ici):

grass.run_command('r.in.gdal',flags='o', input=entree, output=sortie)

Si je voulais tenir compte du drapeau:

drapeau = flags['o'] # -> renvoie vrai ou faux selon que la case est cochée ou non
if drapeau:
    drap = 'o'
    grass.run_command('r.in.gdal',flags=drap,input=entree, output=sortie)
else:
    grass.run_command('r.in.gdal',input=entree, output=sortie)

la commande r.composite est appliquée aux 3 couches résultantes (red, green, blue)

mapred = sortie+".red"
mapgreen = sortie+".green"
mapblue = sortie+".blue"
#fixation de la région sur une des 3 couches
grass.run_command('g.region',rast=mapred)
#et enfin
grass.run_command('r.composite', red=mapred, green=mapgreen, blue=mapblue, output=sortie)

et si l'on veut éliminer les couches intermédiaires red,green et blue:

[grass.run_command('g.remove',rast=i) for i in [mapred,mapgreen,mapblue]]

Le module complet:

r.in.rgb

  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. #****************************************************************
  4. #*
  5. #* MODULE: r.in.rgb
  6. #*
  7. #* AUTHOR(S): Martin Laloux
  8. #*
  9. #* PURPOSE: Charge directement le raster en couleur en éliminant les bandes RGB = r.in.gdal + r.composite + g.remove
  10. #*
  11. #* COPYRIGHT: (C) 2012 Martin Laloux
  12. #* Louvain-la-Neuve, Belgique
  13. #*
  14. #*
  15. #* First Version: 2012/04/16
  16. #*
  17. #*
  18. #* This program is free software under the
  19. #* GNU General Public License (>=v2).
  20. #* Read the file COPYING that comes with GRASS
  21. #* for details.
  22. #*
  23. #****************************************************************
  24.  
  25. #%module
  26. #% description: Charge directement un raster couleur (RGB)
  27. #% keywords: raster
  28. #%end
  29. #%option
  30. #% key: input
  31. #% type: string
  32. #% gisprompt: oldfile,file,dsn
  33. #% answer: .
  34. #% description: Input file
  35. #% required : yes
  36. #%end
  37. #%option
  38. #% key: output
  39. #% type: string
  40. #% gisprompt: oldraster,raster
  41. #% description: Output raster base name
  42. #% required : yes
  43. #%end
  44. #%flag
  45. #% key: o
  46. #% description: Override projection check
  47. #%end
  48.  
  49. import sys, time
  50. import grass.script as grass
  51. def main():
  52. # valeurs provenant de l'interface
  53. entree = options['input']
  54. sortie = options['output']
  55. #drap = flags['o'] -> non utilisé ici
  56.  
  57. # charge le fichier en entrée, entree, vers la couche sortie
  58. grass.run_command('r.in.gdal',flags='o', input=entree, output=sortie)
  59.  
  60. # recomposition du raster original: r.composite à partie de sortie.red, etc.
  61. mapred = sortie+".red"
  62. mapgreen = sortie+".green"
  63. mapblue = sortie+".blue"
  64. # fixation de la région sur une des couches couleurs
  65. grass.run_command('g.region',rast=mapred)
  66. grass.run_command('r.composite', red=mapred, green=mapgreen, blue=mapblue, output=sortie)
  67.  
  68. # élimination des couches red, green, blue
  69. [grass.run_command('g.remove',rast=i) for i in [mapred,mapgreen,mapblue]]
  70.  
  71. # exécution
  72. if __name__ == "__main__":
  73. options, flags = grass.parser()
  74. main()

Où le placer ?

Il faut, bien entendu, que GRASS GIS puisse le retrouver. Il faut donc le placer dans un répertoire qui est dans le chemin de GRASS.

  • répertoire d'installation de GRASS/etc/gui/scripts

Pour Mac OS X, puisque l'application est fournie sous forme de bundle, il est possible de le placer à l'intérieur du bundle (/Applications/GRASS-6.4.app/Contents/MacOS/etc/gui/scripts). Mais si vous mettez à jour l'application (effacement de l'ancienne), plus de module si vous n'y pensez pas. Heureusement William Kyngesburye a pensé à nous et a prévu le coup: il est possible de l'installer dans un répertoire indépendant de l'application:

  • /Library/GRASS/6.4/Modules/bin

Lancement du module

Ce module peut d'ore et déjà être lancé de plusieurs manières:

à partir du sous-menu Launch script du menu File

à partir de la console du Layer Manager

à partir du Shell GRASS

Mais il serait intéressant de créer notre propre menu dans l'interface de GRASS pour le lancer.

Création d'un menu personnalisé dans la barre des menus de GRASS GIS

L'interface de GRASS GIS est programmée en wxPython. Avec wxPython, les menus sont codés dans un seul fichier xml nommé menudata.xml situé dans le répertoire d'installation de GRASS/etc/wxpython/xml/menudata.xml (/Applications/GRASS-6.4.app/Contents/MacOS/etc/wxpython/xml/menudata.xml pour Mac OS X). C'est un fichier xml dont la structure est la suivante:

On reconnait ici tous les menus de GRASS. Ajouter un nouveau menu est un jeu d'enfant:

Et le résultat de l'opération est:

 

Résultats

Toutes les opérations programmées ont bien été effectuées. Notons que pour celui qui le désire, il est aussi possible de programmer toute l'interface en français:

Pour aller plus loin 

Il y a aussi moyen de créer automatiquement le fichier d'aide du module mais je ne l'aborderai pas ici.

Les meilleures informations que j'ai trouvées sur le sujet ne sont ni anglophones, ni francophones, mais italiennes et allemandes:

  • Come scrivere uno script per grass, en italien et déjà cité, pour créer les interfaces;
  • Progammazione & GIS, en italien qui explique de manière très détaillée comment créer des modules en Python, ce qui m'a permis de démarrer (modules en Python v.somma.py, v.elimina.py, v.test.colonna.py, v.quota.py, tin_to_raster.py, tin.hmed.basin.py, tin.lago.py, avec, en particulier la création des fichiers d'aide)

  • Geoprocessing mit Open Source GIS Tools und Python, en allemand, avec une classe en Python, utility, qui illustre la plupart des traitements dont voici le début:

Par après, j'ai aussi regardé les codes sources de la future version 7 (installée chez moi ou visibles sur trac.osgeo.org/grass/browser/grass/trunk/scripts) où tout est en Python.

Notons aussi que www.ing.unitn.it/~grass/software.html propose un autre script plus ancien, nommé aussi r.in.rgb, non écrit en Python, dont le but est de traiter tous les fichiers d'un répertoire avec en plus, l'utilisation de r.patch pour tous les fusionner en une méga couche.

Conclusions

Honnêtement, je trouve que l'écriture de modules de GRASS GIS en Python est beaucoup plus simple que l'écriture d'extensions pour Quantum GIS:

  • aucun tracas avec l'interface, tout est prévu;
  • utilisation de wxPython qui ne s'occupe que de l'interface et pas des traitements, à l'inverse de PyQt pour QGIS où tous les traitements doivent être conformes avec PyQt;
  • traitement direct des commandes de GRASS GIS  + possibilité d'utiliser d'autres modules Python (voir GRASS GIS v. 6.4.2: la nouvelle console Python (Shell Python), exemple d'utilisation simple ou avec le module Shapely).

Ce qu'il manque évidemment, c'est la documentation pour commencer (j'ai du chercher...). J'espère donc avoir apporté ma petite pierre et donné à d'autres l'envie de se lancer

Tous les traitements on été effectués sur Mac OS X avec GRASS GIS version 6.4.2  et Inkscape pour les légendes des figures. 

Site officiel : GRASS GIS
Autres Liens : GRASS GIS pas à pas pour les débutants: 3 - importer des couches matricielles (raster) et importance de la région
Autres Liens : Come scrivere uno script per grass
Autres Liens : Progammazione & GIS
Autres Liens : Geoprocessing mit Open Source GIS Tools und Python
Autres Liens : GRASS GIS v. 6.4.2: la nouvelle console Python (Shell Python), exemple d'utilisation simple ou avec le module Shapely


Creative Commons License
licence Creative Commons Paternité-Pas d'Utilisation Commerciale-Partage des Conditions Initiales à l'Identique Commerciale 2.0 France

Commentaires

Poster un nouveau commentaire

Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement.