#1 Tue 10 August 2010 10:03
- Frédérique
- Participant actif
- Date d'inscription: 13 Jul 2007
- Messages: 51
Batch Python for ArcGIS
Bonjour,
J'ai programmé toute une série de scripts en Pyhton pour des traitements dans ArcGIS.
Je sais dans quel ordre lancer ces scripts mais j'aimerais ne pas devoir les lancer un à un.
Existe-t-il une manière de créer un batch qui reprendrait la succesion de tous ces scripts?
J'ai déjà essayé dans la commande DOS mais je m'y suis sans doute mal prise (fichier texte comprenant les noms des scripts et puis j'appelle le fichier texte dans DOS).
Ca existe en Python? ...Ainsi dans le script Batch Python, je pourrais mettre un argument qui serait repris/appelé dans tous les scripts qui suivent (y en a une vingtaine) .
Merci d'avance pour vos infos,
Bonne journée,
Frédérique
Hors ligne
#2 Tue 10 August 2010 10:41
- Nicolas Granier
- Participant assidu
- Date d'inscription: 19 Apr 2007
- Messages: 271
Re: Batch Python for ArcGIS
Bonjour,
pas besoin d'utiliser des commandes DOS, elles sont pas trop sexy, python sait très bien faire cela.
En python ca ressemblerait à quelque chose comme cela :
Code:
import os os.system (r"c:\dossier\script1.py") os.system (r"c:\dossier\script2.py") ...
il suffit ensuite de lancer ce script.
C'est une façon de faire, on peut aussi imaginer de stocker tous les scripts dans un ordre précis dans une liste et de réaliser une seule boucle pour les lancer tous. Ou bien encore de renommer les scripts dans l'ordre alphabétique et d'utiliser la comande os.listdir() pour récupérer automatiquement tous les noms de scripts dans l'ordre dans une liste.
Il faut bien sur pour que cela fonctionne que les variables d'environnement soit bien renseignées pour lancer le script python.
En ce qui concerne le passage d'argument cela dépend à quel moment et à quel endroit vous passez ces arguments. Il faudrait en savoir plus sur la structure de vos scripts. Un script par fichier ? comment sont structurés les scripts ? Objets - fonctions - procédures ?
A+
Hors ligne
#3 Tue 10 August 2010 11:01
- Frédérique
- Participant actif
- Date d'inscription: 13 Jul 2007
- Messages: 51
Re: Batch Python for ArcGIS
Merci Nicolas pour ton premier élément de réponse.
Pour réponde à tes questions suivantes :
- Mes scripts sont en fait réellement des procédures qui doivent être exécutées dans un ordre bien défini.
- L'argument dont je parle est général et le même pour tous les scripts qui vont tourner. Il s'agit, pour que tu situes mieux, du numéro de la carte pour laquelle nous voulons générer les vecteurs.
- Bref, j'ai 20 scripts, que je veux batcher, qui servent à générer diverses sortes de vecteurs. Ces scripts doivent être appliquées pour 70 cartes différents. L'argument, repris dnas chaque script est le même...le numéro de la carte. C'est pour ça que je me suis dit qu'il porrait être mis comme argument "global" dans le script "batch".
Je ne sais pas si je suis très claire...mais je pense que ça peut aller.
Merci pour ton aide,
Frédérique
PS : D'accord pour dire que la commande DOS est peu sexy dans son style Ghotic ;-) !
Hors ligne
#4 Tue 10 August 2010 12:38
- Spacejo
- Membre
- Lieu: Nancy
- Date d'inscription: 17 Aug 2008
- Messages: 2511
Re: Batch Python for ArcGIS
Salut,
Avec quel outil exécutes tu tes scripts?
La Fenêtre "ligne de commande"?
Si c'est le cas pour le travail en batch --> Scriptgen
Faire des recherches sur le forum avec "scriptgen" ou "générateur de scripts"
A+
Joël
Hors ligne
#5 Tue 10 August 2010 14:41
- Frédérique
- Participant actif
- Date d'inscription: 13 Jul 2007
- Messages: 51
Re: Batch Python for ArcGIS
Re-,
Nicolas, j'ai testé ta proposition de code...y a un petit soucis, il les lance tous en même temps alors que j'aimerais qu'ils soient lancés à la suite les uns des autres.
Joël, je travaille avec Python Shell... je vais faire des petits recherches pour voir de quoi tu me parles. Merci pour l'info en tout cas.
Bon après-midi,
Frédérique
Hors ligne
#6 Tue 10 August 2010 16:44
- dominique.lys
- Participant assidu
- Date d'inscription: 5 Oct 2006
- Messages: 473
- Site web
Re: Batch Python for ArcGIS
Pourquoi ne pas créer un nouveau script qui importe tes autres scripts (s'ils sont bien dans des fichiers distincts) et les exécute dans l'ordre souhaité.
Code:
import script1, script2, script3 def monWorkFlow(numCarte): script1.doScript(numCarte) script2.doScript(numCarte) script3.doScript(numCarte)
Bien sur il faut que chaque script contienne une fonction permettant de lancer la procédure
Code:
def doScript(numCarte): print "traitement 1, faire ça ça ça"
Dernière modification par dominique.lys (Tue 10 August 2010 16:48)
Hors ligne
#7 Wed 11 August 2010 09:44
- Nicolas Granier
- Participant assidu
- Date d'inscription: 19 Apr 2007
- Messages: 271
Re: Batch Python for ArcGIS
Le plus simple mais le moins joli serait d'utiliser la fonction sleep
Elle permet au programme d'attendre un temps défini avant de relancer un autre action.
Elle s'utilise de cette façon :
Code:
import time time.sleep (5)
La variable temps est exprimé en seconde.
Ca peut être une solution simple si tes scripts mettent assez peu de temps à s'executer.
Sinon l'autre solution consisterait à importer tous tes scripts dans un script unique. pour cela il faut ajouter dans les variables d'environnement le chemin d'accès à tes scripts PYTHONPATH = c:\dossier1\script;.... Ainsi un " import script1" fonctionne (sans mettre le ".py")
A+
Hors ligne
#8 Wed 11 August 2010 16:11
- Frédérique
- Participant actif
- Date d'inscription: 13 Jul 2007
- Messages: 51
Re: Batch Python for ArcGIS
Merci pour tous vos conseils !
@Nicolas : La solution "sleep" ne conviendra pas car en fonction des cartes, les temps d'exécution sont différents pour un même script (Carte à la campagne = peu de vecteurs carrefours à générer, contrairement à une carte en zone urbaine par exemple)
@Dominique : J'ai jamais travaillé avec des fonctions donc je vais essayer de m'en sortir mais pour le moment c'est pas gagné! Je ne vois pas très bien comment définir NumCarte, qui est une variable je suppose? Aussi, dans les scripts où je dois placer "def doScript(numCarte):" je dois mettre l'entierté du script avec une indentation sous cette ligne de commande?
...je me suis dit que j'allais essayer une autre solution : Placer la commande "os.system (r"c:\dossier\script2.py")" à la fin du script 1, "os.system (r"c:\dossier\script3.py")" à la fin du script2, etc... mais ça ne fonctionne pas (même si j'ai bien importé le os). Pourquoi?
Bref, on se tient au courant...
Bonne fin de journée,
Frédérique
Hors ligne
#9 Wed 11 August 2010 18:17
- dominique.lys
- Participant assidu
- Date d'inscription: 5 Oct 2006
- Messages: 473
- Site web
Re: Batch Python for ArcGIS
Je dois mettre l'entierté du script avec une indentation sous cette ligne de commande?
Oui c'est ça. Travailler avec des fonctions s'apprend très facilement avec Python, dès que tes scripts prennent de l'ampleur cela devient indispensable.
Actuellement tes script sont sous cette forme:
Code:
# -*- coding:Latin-1 -*- import sys, os import arcgisscripting # Create the Geoprocessor object gp = arcgisscripting.create(9.3) # Récupérer les inputs input1 = sys.argv[1] input2 = sys.argv[2] #Lancer les traitements gp.addmessage("Traitment 1")
Tu peux écrire ceci sous cette forme
Code:
# -*- coding:Latin-1 -*- import sys, os import arcgisscripting def doScript(param1, param2): # Create the Geoprocessor object gp = arcgisscripting.create(9.3) #Execute les traitements gp.addmessage("Traitment 1") # Récupérer les inputs input1 = sys.argv[1] input2 = sys.argv[2] #Lancer les traitements doScript(input1, input2)
Ici tous ce qui est hors de la fonction est exécuté à la lecture du script. C'est donc la dernière ligne du script qui permet de lancer le code contenu dans la fonction.
Tu peux ensuite importer ce script à partir d'un nouveau script de façon à pouvoir accéder aux fonctions qu'il contient. Pour que l'import fonctionne il suffit simplement que tous tes scripts se trouvent dans le même dossier.
L'idée c'est faire qqchose comme ça :
Code:
# -*- coding:Latin-1 -*- import sys, os import script1, script2 # Récupérer les inputs input1 = sys.argv[1] input2 = sys.argv[2] #Lancer les traitements script1.doScript(input1, input2) script2.doScript(input1, input2)
Toutefois il manque encore un détail à régler pour que cela fonctionne. En effet, tout code importé est exécuté ! Dans cet exemple l'import de script1 entraine l'import de arcgisscripting et surtout va exécuter tout le code en dehors de la fonction doScript. Or ce code n'est utile que lorsque script1 est exécuter en tant que programme principal mais n'a pas de sens lorsqu'on l'importe.
Heureusement il est possible de tester si le programme est exécuter en tant que programme principal avec la condition "if __name__ == '__main__':"
Ce qui nous donne pour script1
Code:
# -*- coding:Latin-1 -*- import sys, os import arcgisscripting def doScript(param1, param2): # Create the Geoprocessor object gp = arcgisscripting.create(9.3) #Execute les traitements gp.addmessage("Traitment 1") if __name__ == '__main__': # Récupérer les inputs input1 = sys.argv[1] input1 = sys.argv[2] #Lancer les traitement doScript(input1, input2)
Cette fois le programme peut être importé sans erreur ou exécuté comme programme principal.
Tout ça peut paraitre déroutant au début mais si on résume il a peu de modification à faire:
1. pour chaque script, réinjecter le code dans une fonction avec numCarte pour paramètre
2. si tu veux pouvoir continuer à les exécuter de façon autonome via une toolbox spécifique: introduire le code permettant de lancer la fonction sous la condition if __name__ == '__main__':
3. créer un nouveau programme qui importe les scripts dont tu as besoin, récupère le paramètre saisi dans ta toolbox (numCarte) et exécute les fonctions importées dans le bon ordre.
Je pense que c'est vraiment la solution la plus propre et logique, je trouve que ça n'a pas vraiment de sens d'utiliser os.system pour exécuter des scripts Python avec Python....
Hors ligne