Page 22 sur 23
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 :
- L'ouverture d'un grand nombre de fichiers GML
- Leur conversion en shapes
- Leur édition de structure
- Enfin, leur fusion en un seul shape.
import os import shutil from os import listdir from os.path import isfile, join for g in globals(): del g monRepertoire = 'C:/Users/georg/Downloads/Koln/lines/' # On liste les GML en triant d'éventuels fichiers non GML (GFS par exemple) mesGML_ = [f for f in listdir(monRepertoire) if isfile(join(monRepertoire, f))] mesGML = [val for val in mesGML_ if val.endswith('.gml')] QgsProject.instance().removeAllMapLayers() iface.mapCanvas().refresh() NbreGmlValid = 0 NbreGmlNoValid = 0 # On va stocker les noms des GML correctement ouverts mais aussi leurs appels en layers GmlOuvertsNoms = [] LayersGmlOuverts = [] # Boucle pour ouvrir tous les GML sur QGIS for gml in mesGML : mon_gml = QgsVectorLayer(monRepertoire+gml, gml, 'ogr') # On précise la projection crs = mon_gml.crs() crs.createFromId(25832) mon_gml.setCrs(crs) QgsProject.instance().addMapLayer(mon_gml) # On compte et liste les GML correctement ouverts mais aussi leurs appels en layers if mon_gml.isValid(): print(gml, 'est valide ! OKLM.') NbreGmlValid += 1 GmlOuvertsNoms.append(gml) LayersGmlOuverts.append(mon_gml) # On compte les GML en erreur if not mon_gml.isValid(): print(gml, 'est invalide ! Nous le supprimons.') QgsProject.instance().removeMapLayer(mon_gml.id()) NbreGmlNoValid += 1 print('Nombre de GML correctement ouverts :',NbreGmlValid) print('Nombre de GML invalides et supprimés :',NbreGmlNoValid) # EXPORT EN SHAPE repertoireShapes = 'shapes' pathShape = os.path.join(monRepertoire, repertoireShapes) # On va stocker les noms des shapes correctement ouverts mais aussi leurs appels en layers ShapesOuvertsNoms = [] LayersShapesOuverts = [] # Création d'un répertoire pour accueillir nos shapes if not os.path.exists(pathShape): os.makedirs(pathShape) else: shutil.rmtree(pathShape) os.makedirs(pathShape) # Boucle pour exporter nos GML en shape for s,n in zip(LayersGmlOuverts, GmlOuvertsNoms): nom = n.replace('.gml', '') writer = QgsVectorFileWriter.writeAsVectorFormat(s, pathShape+'/' + nom + '.shp', 'utf-8', driverName='ESRI Shapefile', onlySelected=False) mon_shape = QgsVectorLayer(pathShape+'/' + nom + '.shp', nom, 'ogr') ShapesOuvertsNoms.append(nom) LayersShapesOuverts.append(mon_shape) # OUVRIR LES SHAPES QgsProject.instance().removeAllMapLayers() for x in LayersShapesOuverts: QgsProject.instance().addMapLayer(x) # On va supprimer tous les champs de tous nos shapes sauf 2 champs # Lister les champs d'un layer si besoin et tester avec my_vectorlayer = iface.activeLayer() # D'abord on crée la liste de champs à supprimer for my_shape in LayersShapesOuverts: prov = my_shape.dataProvider() field_names = [field.name() for field in prov.fields()] listeChampSuppression = [] for a in field_names: listeChampSuppression.append(a) listeChampSuppression.remove('gml_id') listeChampSuppression.remove('measuredHe') # Puis on supprime la liste de champs à supprimer for c in listeChampSuppression: with edit(my_shape): my_field = my_shape.fields().indexFromName(c) my_shape.dataProvider().deleteAttributes([my_field]) my_shape.updateFields() # Fusion des shapes parameters = {'LAYERS': ShapesOuvertsNoms,'CRS': 'EPSG:25832','OUTPUT': monRepertoire+'results.shp'} processing.run("qgis:mergevectorlayers", parameters) maFusion = QgsVectorLayer(monRepertoire+'results.shp', 'Ma jolie fusion', 'ogr') QgsProject.instance().addMapLayer(maFusion)