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

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#1 Wed 02 August 2023 12:37

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

QGIS: Lancer un script Python A L'EXTERIEUR de Qgis

Bonjour,


J'avais déjà mis un sujet récent intitulé QGIS/Python: Besoin d'aide pour un script pour sortir des cartes, mais n'ai pas eu de retour

J'ai réussi à faire un script qui fonctionne à l'intérieur de la console Qgis, je vais le joindre en bas de ce message.

Par contre lorsque je j'essaie de le lancer hors de Qgis ça ne fonctionne pas, je ne comprends pas bien ce qu'il faut appeler pour que ça fonctionne.
J'ai essayé en ouvrant un projet vierge dans Qgis et en relançant le code depuis la console Python, là j'avais un premier blocage car il ne me trouvait pas un algorithme, mais ça fonctionne (dans Qgis) maintenant en réinitialisant Processing (cf lignes 84 et suivantes du code), mais par contre ça ne fonctionne toujours pas hors de Qgis.

J'ai placé ce script Python dans le répertoire bin de Qgis, est-ce à un autre endroit qu'il faut le mettre, je ne comprends pas bien ?
Merci d'avance pour votre aide.

Cordialement,

M. Huant

Le code est ici :

Code:

# 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 * 
import qgis.utils

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

chemin_projet_source = r'C:/UsersxxxxxxL/'
nom_projet_source = r'xxxxxxxxx.qgz'
ensemble_projet_chemin = chemin_projet_source + nom_projet_source
chemin_projet_impressions_PDF = r'C:/Users/xxxxxxxxxxS/'

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

# Initialise l'application QGIS 
QgsApplication.setPrefixPath('C:/Program Files/QGIS 3.26.1', True) 
app = QgsApplication([], True) 
app.initQgis() 

# Ouvre le bon projet Qgis

projet_source = QgsProject.instance() 
projet_source.read(ensemble_projet_chemin) 


# Informations de connection à la base en MySQL
uri = 'MySQL:sig,host=xxxxxxx,user=xxxxxxxt,password=xxxxxxx|layername=vxxxxxxxs'
nom_couche_source = ('xxxxxxx')

layer = QgsProject.instance().mapLayersByName('xxxxxxx')[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
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 POQ 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 pour que que ça fasse les calculs puis ensuite

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/xxxxxxxxxx.qml'
POQ.loadNamedStyle(style_existant)
POQ.triggerRepaint()
project = QgsProject.instance()
projectLayoutManager = project.layoutManager()
layout = projectLayoutManager.layoutByName("POQ_disponibilités")
sortie = chemin_projet_impressions_PDF + couche_resultat[:23]+ '.pdf'

# ca bloque à cet endroit, ne trouvait pas l'algorithme printlayouttopdf besoin de reinitialiser les processings vu sur GIS STAck Exchange questions num 321569 et avec les mots clés qgsapplication-processingregistry-loads-providers-however-is-empty-when-called
from processing.core.Processing import Processing
proc = Processing()
proc.initialize()
processing.run("native:printlayouttopdf",{'LAYOUT':'POQ_disponibilités', 'OUTPUT': sortie})

#Ferme le projet et l'application QGIS 
projet_source.clear()
#ferme bien le projet mais pas Qgis 
app.exitQgis()

Hors ligne

 

#2 Fri 04 August 2023 00:33

Robin B
Participant occasionnel
Lieu: Montpellier
Date d'inscription: 31 Jul 2023
Messages: 14

Re: QGIS: Lancer un script Python A L'EXTERIEUR de Qgis

Bonjour,

Concernant votre méthode pour exporter la mise en page en PDF, j'ai l'habitude d'utiliser le code suivant :

Code:

layout_export = projet.layoutManager().layoutByName(nom_layout) # Récupération de la mise en page
        
exporter = QgsLayoutExporter(layout_export) # préparation à l'export
        
exporter.exportToPdf(sortie, QgsLayoutExporter.PdfExportSettings()) # export du pdf

Ensuite pour avoir un script qui puisse être exécuté en dehors de QGIS, j'utilise QGIS à travers la distribution d'OSGEO4W avec la méthode suivante :

   - Ouvrir le répertoire 'Chmm/OSGeo4W/bin' ;
   - Copier le fichier python-qgis-lt.bat ;
   - Le coller dans le même répertoire ('Chmm/OSGeo4W/bin') en lui donnant un nouveau nom ex.: 'script_autonome.bat' ;
   - Ouvrir le fichier script_autonome.bat dans un éditeur de texte ;
   - Sur la dernière ligne, remplacer 'python %*' par 'python cheminduscript.py' ;
   - Enfin avec le planificateur de tâches, il sera possible de mettre en routine l'exécution du fichier 'script_autonome.bat'.

Cette méthode est décrite dans l'article https://www.qgistutorials.com/en/docs/r … _jobs.html (la version de QGIS utilisée est ancienne mais la méthode reste la même).

Hors ligne

 

#3 Mon 07 August 2023 17:03

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

Re: QGIS: Lancer un script Python A L'EXTERIEUR de Qgis

Merci Robin d'avoir pris du temps pour me répondre,


J'ai réussi à faire un powershell qui simplement lance Qgis et ouvre le projet,  et mis le code (avec quelques bibliothèques) dans les macros d'ouverture du projet.
Ca fonctionne quand j'exécute le powershell manuellement. Par contre je n'ai pas les autorisations de sécurité pour le planificateur de tâches.

J'ai aussi essayé la méthode que vous proposiez (merci pour le tuto en anglais il est vraiment bien illustré) mais je n'ai pas le fichier python-qgis-lt.bat seulement le python-qgis.bat dans le répertoire bin. En essayant avec celui ci ça ne fonctionnait pas et je ne sais pas si ça m'affranchira des règles de sécurité du planificateur.

Si ce fichier est manquant faut-il que je relance toute l'installation Osgeo ? C'était très très long.

Encore merci.

Cordialement,

M. Huant

Hors ligne

 

#4 Wed 09 August 2023 09:52

Robin B
Participant occasionnel
Lieu: Montpellier
Date d'inscription: 31 Jul 2023
Messages: 14

Re: QGIS: Lancer un script Python A L'EXTERIEUR de Qgis

Intéressant votre alternative avec le powershell et l'utilisation de macro.

Avec une copie du fichier de python-qgis.bat, le script devrait fonctionner également. Avec vous un message d'erreur qui s'affiche ?

Je ne pense pas qu'il soit nécessaire de relancer toute l'installation d'OSGEO.

Hors ligne

 

#5 Tue 05 September 2023 11:44

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

Re: QGIS: Lancer un script Python A L'EXTERIEUR de Qgis

Bonjour,

Merci pour votre réponse.

Donc on a un powershell qui fonctionne et qui lance le script Qgis mentionné.

Par contre si on veut lancer ce powershell comme une tâche planifiée sous Windows cela ne fonctionne que avec l'utilisateur connecté (snif Cron et Linux..)
Quelqu'un a-t-il déjà travaillé sur cette problématique ?
Notre administrateur réseau me dit que cela vient du fait que l'on utilise une interface graphique, du coup je me retrouve avec la question, comment modifier le script ci-dessus pour qu'il fonctionne SANS iface ?

Beaucoup de questions du coup. Merci d'avance pour votre aide.

M. Huant

Hors ligne

 

#6 Wed 13 September 2023 20:49

louloupzh18
Participant occasionnel
Lieu: Le Mans
Date d'inscription: 9 Apr 2015
Messages: 11

Re: QGIS: Lancer un script Python A L'EXTERIEUR de Qgis

Bonjour,

iface est une variable qui va interroger l'interface graphique de QGIS pour identifier vos couches.
Pour contourner cette pratique, essayez de définir vos couches à partir de leur emplacement sur le pc/réseau de cette manière :

Code:

from qgis.core import QgsProject, QgsVectorLayer

# Chemin du fichier Shapefile
shapefile_path = "C:/chemin/vers/votre/fichier.shp"

# Créer une nouvelle couche vectorielle
vector_layer = QgsVectorLayer(shapefile_path, "Nom de la couche", "ogr")

A priori de cette manière cela enlèvera les requêtes réalisées sur l'interface graphique mais il y en a peut-être d'autres. Pouvez-vous tester cette solution ?

Bien cordialement,

louloupzh

Dernière modification par louloupzh18 (Wed 13 September 2023 20:51)

Hors ligne

 

#7 Wed 25 October 2023 15:28

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

Re: QGIS: Lancer un script Python A L'EXTERIEUR de Qgis

Bonjour tout le monde,


Je viens vous donner des nouvelles de notre projet de cartographie automatique, qui a abouti
Nous sommes finalement passés sous Linux, car nous n'avons pas trouvé la solution Windows/Powershell pour utiliser l'interface graphique.

Donc le projet de cartographie automatique est basé sur :
- un script python, qui a été copié dans la macro d'ouverture d'un fichier .qgz
- un crontab pour l'automatisation des procédures
et - un fichier exécutable .sh (équivalent d'un .bat) qui articule l'ensemble

En détail on a donc :

LE CRONTAB qui s'exécute toutes les 30 minutes

Code:

*/30 * * * * sh /nom_du_répertoire/nom_du_script.sh >> /nom_du_répertoire/nom_du_log.log 2>&1

LE SCRIPT SH

Celui-ci contient le code suivant :

Code:

#!/bin/bash

# Efface les fichiers temporaires avant nouvelle exécution du premier fichier qgis 
rm -r /nom_du_répertoire_des_objets_temporaires_du_premier_fichier_qgis/*

#[b] Crée un instance graphique virtuelle : CA C'EST TRES IMORTANT POUR UTILISER L'INTERFACE GRAPHIQUE DE QGIS
Xvfb :15 &
export DISPLAY=:15[/b]

# Lance le premier projet qgis et le ferme après 1 min d'activité
timeout 1m /répertoire_premier_projet/premier_fichier_qgis.qgz

# Copie le fichier xxxx.gpkg pour qu’il soit utilisé pour le 2e projet Qgis
cp -f /nom_du_répertoire_des_objets_temporaires_du_premier_fichier_qgis/xxxv.gpkg   /répertoire__temporaire_2e_projet/

# Lance le 2e projet qgis et le fermeaprès 2 min d'activité
timeout 2m /répertoire__2e_projet/2e_projet.qgz

# Efface les fichiers temporaires après exécution du 2e projet
rm -r /répertoire__temporaire_2e_projet/*

Quant au script Python de la macro je l'avais déjà publié sous un autre post

Hors ligne

 

Pied de page des forums

Powered by FluxBB