banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Pour sa 21ème année, l’association GeoRezo a toujours besoin de vous !

10€ = 1 mois de frais bancaires ; 15€ = 12 mois de nom de domaine ; 30€ = 1 semaine de location des serveurs …

Faire un don 

Retrouver nos membres bienfaiteurs

#1 Tue 11 July 2023 11:23

myh89
Participant occasionnel
Date d'inscription: 24 Oct 2016
Messages: 15

QGIS/Python: Besoin d'aide pour un script pour sortir des cartes

Bonjour, je demande de l’aide pour un script Python qui permettrait d’imprimer (ou du moins de créer des fichiers pdf) depuis Qgis toutes les ½ heures.

Ce script (qui pourrait être lancé depuis un powershell Windows, donc penser à importer toutes les librairies nécessaires) :

- Ouvrirait un projet Qgis existant depuis un répertoire existant
- Dans ce projet sont déjà présents des couches et une mise en page, j’aurais besoin de copier une couche (qui vient d’un serveur MysQL) vers une autre couche (car pas le droit en écriture) avec tous ces éléments.
- D’ajouter un champ de calcul dans la nouvelle couche pour sommer plusieurs colonnes
- Symboliser cette nouvelle couche avec un style existant
- Ouvrir une mise en page existante et rafraichir en rajoutant la nouvelle table. Dans cette mise en page le titre inclut la date et l’heure mis à jour
- Enregistrer la mise en page au format pdf.

Je bloque déjà pour ouvrir ma table MySQL.. Merci beaucoup pour votre aide.

M. Huant

Hors ligne

 

#2 Tue 11 July 2023 12:43

SANTANNA
Moderateur
Lieu: Angers
Date d'inscription: 18 Jan 2008
Messages: 3963

Re: QGIS/Python: Besoin d'aide pour un script pour sortir des cartes

Bonjour,

Je bloque déjà pour ouvrir ma table MySQL..


Savoir ce que vous avez essayé et à quel endroit ça coince aiderait peut-être les gens à vous aider...

Mais plus généralement, et même si j'ignore votre niveau en Python, puis-je vous suggérer de passer par le modeleur graphique pour essayer de construire chacune de vos briques? Des algorithmes existent pour (je pense) chacune des grandes étapes de votre procédure. Et une fois que le modèle sera fonctionnel, vous pourrez le convertir en script, et paramétrer votre fréquence d'exécution par dessus.
Et lorsque vous serez coincés sur des éléments bien précis dans la mise en œuvre, il sera plus facile de décrire ce que c'est et, je l'espère, trouver de l'aide.

Hors ligne

 

#3 Fri 21 July 2023 15:47

myh89
Participant occasionnel
Date d'inscription: 24 Oct 2016
Messages: 15

Re: QGIS/Python: Besoin d'aide pour un script pour sortir des cartes

Bonjour Santanna et toute personne qui accepterait de m’aider, merci déjà aux personnes qui l’on fait par d’autres canaux.

J’ai essayé d’utiliser le modèle Builder mais je n’ai pas trouvé ce qu’il me fallait. J'ai aussi utilisé l'historique du menu Traitement pour voir comment s'écrivent les commandes que j'exécute mais il manque certaines interactions.

Je reexplique donc ce que j’ai fait :

1- La syntaxe pour ouvrir un projet Qgis existant depuis un répertoire existant ne m’intéresse pas pour l’instant, on considère le projet ouvert et les couches chargée dont celle en MySQL.

J’ai juste noté comme variables :
2 - chemin_projet_source = r'C:/Usersxxxxx/(..)/' : j'y ai les droits en écriture

3 - Pour le nom du shapefile de destination qui change toutes les 30 minutes, j'ai écrit ça

from datetime import datetime

datajour = str(datetime.now())
# pour raccourcir le nom et l’heure, #jusqu’ à l’heure
datajourH = datajour[:13]
#il faut couper pour ne pas avoir les 2 points dans le nom du fichier
minutes = datajour[15:16]

couche_resultat = 'POQ du ' + datajourH + 'h' + minutes + '.shp'

4- Pour gérer le MySQL

uri = 'MySQL:nom_de_ma_base,host=adresse_IP,user=mon_nom t,password=mon_pass|layername=nom_de_table'

5- Pour trouver le nom des couches en faisant attention à l’indentation
for id, layer in QgsProject.instance().mapLayers().items():
    print(layer.name())

# Attribuer ce nom – attention c’est seulement le nom
nom_couche_source = ('nom de la base _ nom de  la table')

si on l’attribue directement et qu’on cherche le type on a une liste et non pas une vector layer

couche_source = QgsProject.instance().mapLayersByName ('nom de la base _ nom de  la table')
type(couche_source)
<class 'list'>

pour l’attribuer en manuel on peut faire ça

couche_source = iface.activeLayer()
couche_source.id()xxxxxxxxx5ecf14a0'
couche_source.type()
<QgsMapLayerType.VectorLayer: 0>

Mais sans utiliser active Layer ??

5 - Et donc je bloque toujours pour enregistrer ma table MySQL en une nouvelle couche shapefile (avec le nom de cla couche_resultat) en ayant essayé

5A QgsVectorFileWriter : les arguments ne sont pas les bons
5B processing.run("native:savefeatures", {'INPUT':'MySQL:sig,host=IP,user=xxxx,password=xxxx,tables=xxxx|layername=xxxs|geometrytype=Point','OUTPUT':'C:/UserxxxxxL/','LAYER_NAME':'xxxxx','DATASOURCE_OPTIONS':'','LAYER_OPTIONS':''})

en 5B ça me crée un faux Geopackage sans nom (juste le fichier avec l'extension gpkg), j'ai essayé de mettre ESRI Shapefile dans DataSource ou Dans layer Options, même résultat...

Bref pour l'instant ça n'est pas la gloire, et je ne comprends pas pourquoi Qgis et MySQL s'aiment aussi peu (même remarque de notre prestataire..)

Merci d'avance pour votre aide. Je continue aussi avec ChatGPT qui me donne plein de syntaxes alternatives qui ne fonctionnent pas. Alors que quand je fais les manipulations en manuel ça fonctionne. L'idée du 5B m'est venu en utilisant l'historique des traitements, mais il manque le moment où ça demande si on veut faire un fichier temporaire, celui pour le CRS, et celui pour le type de ficher (gpkg par défaut, shapefile ensuite, etc)

MERCI MERCI.

M. Huant

Hors ligne

 

#4 Fri 21 July 2023 16:30

myh89
Participant occasionnel
Date d'inscription: 24 Oct 2016
Messages: 15

Re: QGIS/Python: Besoin d'aide pour un script pour sortir des cartes

J'ai réussi la partie export avec les étapes suivantes (en 5A méthode Writer donc)

1 datajour = str(datetime.now())
2 datajourH = datajour[:13]
3 minutes = datajour[14:16]
4 couche_resultat = 'POQ du ' + datajourH + 'h' + minutes + '.shp'
5 un print pour vérifier le temps
6 chemin_shapefile = chemin_projet_source + couche_resultat
7 writer = QgsVectorFileWriter.writeAsVectorFormat(couche_source, chemin_shapefile, "UTF-8", couche_source.crs(), "ESRI Shapefile")

Ce qu'il me manque donc c'est de réussir à avoir la couche source dans utiliser l'active layer mais le nom de la couche/table MySQL

Merci pour votre aide et bon week-end à venir.

M. Huant

Hors ligne

 

#5 Fri 28 July 2023 14:55

myh89
Participant occasionnel
Date d'inscription: 24 Oct 2016
Messages: 15

Re: QGIS/Python: Besoin d'aide pour un script pour sortir des cartes

Bonjour tout le monde,

Suite à mon dernier message, j'ai réussi écrire mon script Python et à le faire fonctionner depuis l'intérieur de Qgis.
Cependant j'aimerais le lancer en automatique la nuit et donc besoin de le traduire en Powershell. Quelqu'un saurait-il m'aider ? Depuis Powershell je sais ouvrir le projet Qgis mais pas interagir avec lui.

MERCI D'AVANCE POUR VOTRE AIDE, ci dessous le script qui fonctionne depuis Qgis.


# Appel des librairies nécessaires
from qgis import processing
from qgis.core import QgsApplication, QgsProject, QgsLayerTreeGroup, QgsLayerTreeLayer, QgsExpression, QgsExpressionContext, QgsExpressionContextUtils
from qgis.utils import iface
from PyQt5.QtCore import QVariant

from datetime import datetime
from qgis.core import *

# Variables d'environnement, noms des répertoires, projets, etc

chemin_projet_source = r'C:/Users/toto/'
nom_projet_source = r'tata.qgz'
ensemble_projet_chemin = chemin_projet_source + nom_projet_source
chemin_projet_impressions_PDF = r'C:/Users/lulu/'

# NOM DES VARIABLES
#uri
#couche_source
#couche_resultat
# chemin_projet_impressions_PDF

# Informations de connection à la base en MySQL

uri = 'MySQL:sig,host=xxxxxx,user=xxxxx,password=cxxxx|layername=xxxxx'

# Ici pour avoir la liste des couches, mais pas nécessaire car on utilise toujours la même coiuche 'titi'


for id, layer in QgsProject.instance().mapLayers().items():
    print(layer.name())

   
nom_couche_source = ('titi')

layer = QgsProject.instance().mapLayersByName('titi')[0]
iface.setActiveLayer(layer)

couche_source = iface.activeLayer()
datajour = str(datetime.now())
datajourH = datajour[:13]
minutes = datajour[14:16]
couche_resultat = 'POQ du ' + datajourH + 'h' + minutes + '.shp'
chemin_shapefile = chemin_projet_source + couche_resultat

# Syntaxe qui fonctionne pour convertir le MySQL en shapefile


writer = QgsVectorFileWriter.writeAsVectorFormat(couche_source, chemin_shapefile, "UTF-8", couche_source.crs(), "ESRI Shapefile")
vlayer = QgsVectorLayer(chemin_shapefile, couche_resultat[:23], "ogr")
QgsProject.instance().addMapLayer(vlayer)

# A ce niveau la nouvelle couche avec date et heure est ajoutée dans la liste des couches et devient la nouvelle active layer
nom_champ_somme = 'DISPO'
colonnes_somme = ['nb_dispo', 'nb_dispo5', 'nb_dispo_s','nb_dispo_1' ]
expression_somme = '+'.join(colonnes_somme)
contexte_expression = QgsExpressionContext()
POQ = iface.activeLayer()
contexte_expression.setFeature(POQ.getFeature(0))
expression = QgsExpression(expression_somme)
expression.prepare(contexte_expression)
POQ.dataProvider().addAttributes([QgsField(nom_champ_somme, QVariant.Int)])
POQ.updateFields()

# a cet endroit là ça a bien créé le champ DISPO
index_champ_somme = POQ.fields().indexFromName(nom_champ_somme)
POQ.startEditing()
# ca ouvre la couche en édition
for entite in POQ.getFeatures():
    contexte_expression.setFeature(entite)
    valeur_somme = expression.evaluate(contexte_expression)
    POQ.changeAttributeValue(entite.id(), index_champ_somme, valeur_somme)
# Là il faut faire un entrée dans la console Python pour que que ça fasse les calculs puis ensuite, mais marche ok si on lance le script Python d'un coup

POQ.commitChanges()
# ca enregistre les changements et ferme le mode edition

# Attribuer le style qui va bien et est déjà enregistré en qml
style_existant = r'C:/Users/zaza.qml'
POQ.loadNamedStyle(style_existant)
POQ.triggerRepaint()
project = QgsProject.instance()
projectLayoutManager = project.layoutManager()
layout = projectLayoutManager.layoutByName("zozo")
#iface.openLayoutDesigner(layout) # il faudra penser à fermer le gestionnaire de mise en page après
#iface.showLayoutManager()
sortie = chemin_projet_impressions_PDF + couche_resultat[:23]+ '.pdf'
processing.run("native:printlayouttopdf",{'LAYOUT':'zozo', 'OUTPUT': sortie})

# Ici le resultat est OK = un pdf avec la carte à jour dans le bon répertoire. Il faudra penser à fermer Qgis proprement


MERCI DE VOTRE AIDE POUR M'AIDER à FAIRE FONCTIONNER CE SCRIPT VIA POWERSHELL

M. Huant

Hors ligne

 

Pied de page des forums

Powered by FluxBB