Skip to Content

Python : créer automatiquement des fichiers styles (qml) de QGIS à partir de fichiers ou de shapefiles avec des colonnes/champs R, G, B

Niveau Intermédiaire
Logiciels utilisés Python
Plateforme Windows | Mac | Linux | FreeBSD

Récemment, deux questions similaires ont été posées sur gis.stackexchange.com/questions :

« How to use a field-to-RGB mapping for symbology in QGIS? » (gis.stackexchange.com/questions/15135/how-to-use-a-field-to-rgb-mapping-for-symbology-in-qgis/15299)

et

« How to create a style file for QGIS from a plain text file? »(gis.stackexchange.com/questions/15185/how-to-create-a-style-file-for-qgis-from-a-plain-text-file)

C'est à dire, comment utiliser  les valeurs R,G,B situés dans des colonnes d'un fichier texte pour créer automatiquement un fichier style de Quantum GIS ?

Question à laquelle j'ai répondu (gis.stackexchange.com/questions/15135/how-to-use-a-field-to-rgb-mapping-for-symbology-in-qgis/15299#15299) avec des scripts en Python que je présente ici, sans utiliser QGIS.

Le type de fichier est un fichier délimité avec une colonne classe et des colonnes avec les  valeurs R, G, B correspondantes. Mais il est aussi possible de le faire directement à partir de fichiers shapefiles avec les champs équivalents.

Les fichiers styles de Quantum GIS (QGIS)

Ce sont des fichiers XML qui paraissent complexes au premier abord (xxxx.qml figuré ici en partie) :

L'examen synthétique des balises utilisées est plus intéressant car il est possible de reconnaître toutes les caractéristiques disponibles dans les propriétés de QGIS :


Les balises les plus importantes, dans le cas qui nous concerne (polygones avec une couleur de fond), sont :

  • <uniquevalue> -> classification par Valeur unique ;
  • <classificationattribute> et <classificationfield> -> classe utilisée pour la classification (FORM ici) ;
  • <uppervalue> et <lowervalue>  valeur de la classe et étiquette;
  • <outlinecolor> et <fillcolor> -> couleur(s) du contour et du remplissage avec les valeurs R,G,B

Il est dès lors tout à fait possible de recréer un fichier style simplifié en ne retenant que les balises désirées :

Le fichier style résultant (créé avec les scripts Python présentés dans la suite) marche avec toutes les versions de QGIS :

Création de fichiers styles avec Python

Comme ce sont des fichiers XML, il est donc possible de les créer automatiquement avec Python et le module ElementTree déjà examiné sur le Portail : « XML et Python pour les Sigistes ou pourquoi il n'y a pas besoin de réinventer la roue... », sans utiliser QGIS.

à partir d'un fichier texte délimité (colonnes : Classe, R, G, B)

Le fichier traité est le suivant (classe, valeur R, valeur G, valeur B)

AE,143,255,255
BOU,255,255,255
FAM,244,250,202
PP,195,239,218
etc.

(ce sont en fait des sigles de formations géologiques)

création automatique d'un fichier style à partir d'un fichier texte délimité

  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3.  
  4. """
  5. creastyle.py
  6. permet la création de fichier style (.qml) de Quantum GIS à partir d'un
  7. fichier texte avec des valeurs RGB du type (FORM, R, G, B):
  8. AE,250,125,32
  9. etc.
  10. par Martin Laloux
  11. version du 10/2011 pour le Portail SIG
  12. """
  13.  
  14. from xml.etree import cElementTree as ET
  15. from string import *
  16.  
  17. """ création des élements de la balise qgis"""
  18. intro = ET.Element("qgis")
  19. transp = ET.SubElement(intro,"transparencyLevelInt")
  20. transp.text = '255'
  21. classatr = ET.SubElement(intro, "classificationattribute")
  22. classatr.text= "FORM"
  23. typec = ET.SubElement(intro,"uniquevalue")
  24. classif = ET.SubElement(typec,"classificationfield")
  25. classif.text="FORM"
  26.  
  27.  
  28. class symbol:
  29. """création des éléments de la balise symbole"""
  30. def __init__(self,valeurs=[]):
  31. self.typec= typec
  32. self.valeurs = valeurs
  33. self.cle = ['FORM','R','G','B']
  34. self.donnees = dict(zip(self.cle,self.valeurs))
  35. self.symb = ET.SubElement(typec,"symbol")
  36. self.lower = ET.SubElement(self.symb, "lowervalue")
  37. self.upper = ET.SubElement(self.symb, "uppervalue")
  38. self.outline = ET.SubElement(self.symb,"outlinecolor")
  39. self.outsty = ET.SubElement(self.symb, "outlinestyle")
  40. self.outtail = ET.SubElement(self.symb, "outlinewidth")
  41. self.fillc = ET.SubElement(self.symb,"fillcolor")
  42. self.fillp = ET.SubElement(self.symb,"fillpattern")
  43.  
  44. def creation(self):
  45. self.lower.text = self.donnees['FORM']
  46. self.upper.text = self.donnees['FORM']
  47. self.outsty.text="SolidLine"
  48. self.outtail.text="0.26"
  49. self.outline.set("red",self.donnees['R'])
  50. self.outline.set("green",self.donnees['G'])
  51. self.outline.set("blue",self.donnees['B'])
  52. self.fillc.set("red",self.donnees['R'])
  53. self.fillc.set("green",self.donnees['G'])
  54. self.fillc.set("blue",self.donnees['B'])
  55. self.fillp.text = "SolidPattern"
  56.  
  57.  
  58.  
  59. def traitement():
  60. """traitement du fichier texte et écriture du fichier style"""
  61. # ouverture du fichier texte et remplissage de la balise symbol
  62. fichier = "test.txt"
  63. for elem in [split(line,',') for line in open(fichier,"r")]:
  64. symb = symbol(elem)
  65. symb.creation()
  66.  
  67. # écriture du ficher style final
  68. fich_style = ET.ElementTree(intro)
  69. fich_style.write("monstyle.qml")
  70.  
  71. if __name__ == '__main__':
  72. traitement()

Ce script génère le fichier style simplifié (qml) présenté plus haut.

à partir d'un fichier shapefile  (champs : Classe, R, G, B)

Le module le plus simple à utiliser pour traiter les shapefiles en Python a aussi déjà été présenté sur le Portail : « Python et les shapefiles (suite) ou le module le plus simple à utiliser (un seul fichier, sans dépendance) ». C'est le module pyshp (Python Shapefile Library).

La table associée est la suivante (avec des doublons, courants dans les shapefiles, qu'il faut éliminer dans le fichier style résultant) :

La base du traitement est la même, hormis qu'il faut importer le module shapefile et l'utiliser dans

def traitement():

pour traiter les valeurs des champs du shapefile.

création automatique d'un fichier style à partir d'un fichier shapefile

  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3.  
  4. """
  5. creastyle2.py
  6. permet la création de fichier style (.qml) de Quantum GIS à partir d'un
  7. fichier shapefile avec des champs du type (FORM, R, G, B):
  8. AE,250,125,32
  9. etc.
  10. par Martin Laloux
  11. version du 10/2011 pour le Portail SIG
  12. """
  13.  
  14. from xml.etree import cElementTree as ET
  15. from string import *
  16. import shapefile
  17. _____________________________________________________
  18. [....même script que le précédent...]
  19. _____________________________________________________
  20.  
  21. # traitement des doublons éventuels
  22. traités = []
  23.  
  24. def traitement():
  25. """traitement du fichier shapefile et écriture du fichier style"""
  26. # ouverture du fichier shapefile et remplissage de la balise symbol
  27. sf = shapefile.Reader("essai")
  28. for rec in enumerate(sf.records()):
  29. if rec[1][0] not in traités:
  30. traités.append(rec[1][0])
  31. symb = symbol(rec[1])
  32. symb.creation()
  33. else:
  34. continue
  35.  
  36. # écriture du ficher style final
  37. fich_style = ET.ElementTree(intro)
  38. fich_style.write("monstyle.qml")
  39.  
  40. if __name__ == '__main__':
  41. traitement()

Ce script génère aussi le fichier style simplifié (qml) présenté plus haut.

Résultat (« Charger le style »)

 

Conclusions

En pratique, j'utilise ces scripts depuis longtemps, mais avec un fichier-base SQLite contenant toutes les valeurs nécessaires avec les champs R,G, B, et des shapefiles, d'abord traités avec le module gdal/ogr puis avec le module shapefile (pyshp), beaucoup plus simple à utiliser. Cela me permet aussi d'ordonner les classes suivant l'ordre que je veux (stratigraphique). J'en utilise d'autres pour les éléments points et/ou (poly)lignes.

Une fois que la structure d'un fichier style est comprise et qu'on connait le résultat qu'on veut obtenir, c'est facile (il est possible de créer des fichiers pour tous les types de styles, de choisir les balises à figurer, etc.).

Tous les traitements ont été effectués sur Mac OS X et  avec Python 2.6.1

Site officiel : XML et Python pour les Sigistes ou pourquoi il n'y a pas besoin de réinventer la roue...
Site officiel : Python et les shapefiles (suite) ou le module le plus simple à utiliser (un seul fichier, sans dépendance)
Site officiel : pyshp (Python Shapefile Library)


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

Commentaires

site plugin de QGIS

Les 2 scripts ont été publiés sur

plugins.qgis.org/snippets/

Poster un nouveau commentaire

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