Index de l'article

Fusion de couches

Un cas d'école : un collaborateur récupère un grand nombre de fichiers de données et souhaite les exploiter proprement. Il s'agit de plusieurs centaines de fichiers cadastraux allemands.

Téléchargez, dézippez et ouvrez la couche Koln gml.zip.

Le but est d'automatiser :

  1. L'ouverture d'un grand nombre de fichiers GML
  2. Leur conversion en shapes
  3. Leur édition de structure
  4. Enfin, leur fusion en un seul shape.
  1. import os
  2. import shutil
  3. from os import listdir
  4. from os.path import isfile, join
  5.  
  6. # On supprime les futures variables utilisées, car certaines semblent gêner les exécutions multiples du script
  7. my_var = ['ShapesOuvertsNoms', 'LayersShapesOuverts', 's', 'n', 'mon_shape', 'repertoireShapes', 'pathShape', 'nom', 'writer']
  8. for v in my_var:
  9. if v in globals():
  10. del v
  11.  
  12. monRepertoire = 'C:/Users/Georges/Downloads/Koln/lines/'
  13.  
  14. # On liste les GML en triant d'éventuels fichiers non GML (GFS par exemple)
  15. mesGML_ = [f for f in listdir(monRepertoire) if isfile(join(monRepertoire, f))]
  16. mesGML = [val for val in mesGML_ if val.endswith('.gml')]
  17.  
  18. QgsProject.instance().removeAllMapLayers()
  19. iface.mapCanvas().refresh()
  20.  
  21. NbreGmlValid = 0
  22. NbreGmlNoValid = 0
  23.  
  24. # On va stocker les noms des GML correctement ouverts mais aussi leurs appels en layers
  25. GmlOuvertsNoms = []
  26. LayersGmlOuverts = []
  27.  
  28. # Boucle pour ouvrir tous les GML sur QGIS
  29. for gml in mesGML :
  30. mon_gml = QgsVectorLayer(monRepertoire+gml, gml, 'ogr')
  31.  
  32. # On précise la projection
  33. crs = mon_gml.crs()
  34. crs.createFromId(25832)
  35. mon_gml.setCrs(crs)
  36. QgsProject.instance().addMapLayer(mon_gml)
  37.  
  38. # On compte et liste les GML correctement ouverts mais aussi leurs appels en layers
  39. if mon_gml.isValid():
  40. print(gml, 'est valide ! OKLM.')
  41. NbreGmlValid += 1
  42. GmlOuvertsNoms.append(gml)
  43. LayersGmlOuverts.append(mon_gml)
  44.  
  45. # On compte les GML en erreur
  46. if not mon_gml.isValid():
  47. print(gml, 'est invalide ! Nous le supprimons.')
  48. QgsProject.instance().removeMapLayer(mon_gml.id())
  49. NbreGmlNoValid += 1
  50.  
  51. print('Nombre de GML correctement ouverts :',NbreGmlValid)
  52. print('Nombre de GML invalides et supprimés :',NbreGmlNoValid)
  53.  
  54. # EXPORT EN SHAPE
  55. repertoireShapes = 'shapes'
  56. pathShape = os.path.join(monRepertoire, repertoireShapes)
  57.  
  58. # On va stocker les noms des shapes correctement ouverts mais aussi leurs appels en layers
  59. ShapesOuvertsNoms = []
  60. LayersShapesOuverts = []
  61.  
  62. # Création d'un répertoire pour accueillir nos shapes
  63. if not os.path.exists(pathShape):
  64. os.makedirs(pathShape)
  65. else:
  66. shutil.rmtree(pathShape)
  67. os.makedirs(pathShape)
  68.  
  69. # Boucle pour exporter nos GML en shape
  70. for s,n in zip(LayersGmlOuverts, GmlOuvertsNoms):
  71. nom = n.replace('.gml', '')
  72. writer = QgsVectorFileWriter.writeAsVectorFormat(s, pathShape+'/' + nom + '.shp', 'utf-8', driverName='ESRI Shapefile', onlySelected=False)
  73.  
  74. mon_shape = QgsVectorLayer(pathShape+'/' + nom + '.shp', nom, 'ogr')
  75.  
  76. ShapesOuvertsNoms.append(nom)
  77. LayersShapesOuverts.append(mon_shape)
  78.  
  79. # OUVRIR LES SHAPES
  80. QgsProject.instance().removeAllMapLayers()
  81. for x in LayersShapesOuverts:
  82. QgsProject.instance().addMapLayer(x)
  83.  
  84. # On va supprimer tous les champs de tous nos shapes sauf 2 champs
  85. # Lister les champs d'un layer si besoin et tester avec my_vectorlayer = iface.activeLayer()
  86. # D'abord on crée la liste de champs à supprimer
  87. for my_shape in LayersShapesOuverts:
  88. prov = my_shape.dataProvider()
  89. field_names = [field.name() for field in prov.fields()]
  90. listeChampSuppression = []
  91.  
  92. for a in field_names:
  93. listeChampSuppression.append(a)
  94.  
  95. listeChampSuppression.remove('gml_id')
  96. listeChampSuppression.remove('measuredHe')
  97.  
  98. # Puis on supprime la liste de champs à supprimer
  99. for c in listeChampSuppression:
  100. with edit(my_shape):
  101. my_field = my_shape.fields().indexFromName(c)
  102. my_shape.dataProvider().deleteAttributes([my_field])
  103. my_shape.updateFields()
  104.  
  105. # Fusion des shapes
  106. parameters = {'LAYERS': ShapesOuvertsNoms,'CRS': 'EPSG:25832','OUTPUT': monRepertoire+'results.shp'}
  107. processing.run("qgis:mergevectorlayers", parameters)
  108. maFusion = QgsVectorLayer(monRepertoire+'results.shp', 'Ma jolie fusion', 'ogr')
  109. QgsProject.instance().addMapLayer(maFusion)
Liens ou pièces jointes
Accéder à cette adresse URL (https://hg-map.fr/extern/data/shapes/france/chemin_de_fer.zip)chemin_de_fer.zip[ ]0 Ko
Télécharger ce fichier (data_BDTOPO_V3_Dep05_adresse.zip)data_BDTOPO_V3_Dep05_adresse.zip[ ]3889 Ko
Télécharger ce fichier (data_IRIS_2019.zip)data_IRIS_2019.zip[ ]45905 Ko
Télécharger ce fichier (decathlon_france.zip)decathlon_france.zip[308 magasins Décathlon français depuis OSM le 27 décembre 2020]11 Ko
Accéder à cette adresse URL (https://hg-map.fr/extern/data/shapes/france/eau.zip)eau.zip[ ]0 Ko
Télécharger ce fichier (glaciers.zip)glaciers.zip[ ]231 Ko
Télécharger ce fichier (iso_iris.zip)iso_iris.zip[Des zones isochrones à 15 minutes autour de 308 POIs.]12125 Ko
Télécharger ce fichier (Koln GML.zip)Koln gml.zip[ ]2818 Ko
Télécharger ce fichier (peaks.zip)peaks.zip[ ]14 Ko
Télécharger ce fichier (peaks_selection.zip)peaks_selection.zip[ ]1 Ko
Télécharger ce fichier (simple_countries.zip)simple_countries.zip[ ]1880 Ko
Accéder à cette adresse URL (https://hg-map.fr/extern/data/shapes/france/sol.zip)sol.zip[ ]0 Ko
Accéder à cette adresse URL (https://hg-map.fr/extern/data/shapes/france/troncons_routes.zip)troncons_routes.zip[ ]0 Ko