Les scripts Python qui s'exécutent à l'intérieur d'ArcMap par rapport à ceux qui s'exécutent à l'extérieur?

10

Je commence tout juste à entrer dans les scripts Python pour le travail.

Je crée actuellement un script pour automatiser un processus.

Fondamentalement, il demande à l'utilisateur le nom du client, obtient une projection si disponible, crée un répertoire sur le lecteur C: pour le client, crée une géodatabase fichier spécifique au client, crée le jeu de données requis et crée des classes d'entités spécifiques aux données des clients. Finalement, il ajoutera également les champs requis à chaque classe d'entités et probablement d'autres choses.

J'ai commencé cela sans vraiment connaître la bonne étiquette des scripts Python pour ArcMap. Mais ce que j'ai créé jusqu'à présent ne fonctionnera qu'en dehors d'ArcMap, je crois.

Est-ce acceptable?

Au lieu d'obtenir une entrée utilisateur via arcpy.getparamaterastext (), que je viens de découvrir, j'utilise raw_input ().

Est-ce correct?

Cela fonctionne, je ne suis simplement pas sûr que ce soit une bonne façon de faire des scripts.

Voici le code que j'ai jusqu'à présent.

import sys
import arcpy
import os

#Records name of the client
client = raw_input("Enter the name of the client: (letters and underscores only) \n")

#Records filepath of client to be created
clientpath = "C:/" + client

#Inquires if projection file exists
projection = raw_input("Is there a .prj or .shp available with correct projection? Y or N \n")

#Records the projection location if available
if projection.upper() == "Y":
    spatialr = raw_input("Drag the .prj or .shp here to record the filepath \n")
    nspatialr = spatialr.replace('"', "")
elif projection.upper() == "N":
    alert = raw_input("You must add the spatial reference manually, hit enter to continue. \n")
elif projection.upper() != "N" or "Y":
    exit = raw_input("That is not a valid response. Try again. \n")
    sys.exit()

#Checks if client folder exists; if not, creates one
if not os.path.exists(clientpath):
    os.makedirs(clientpath)

#Variable for file geodatabase location
FGBpath = clientpath + "/" + client + ".gdb"

#Checks if client file geodatabase exists; if not, creates one
if not arcpy.Exists(FGBpath):
    arcpy.CreateFileGDB_management(clientpath, client)

#Variable for dataset location
FDatasetpath = clientpath + "/" + client + ".gdb" + "/Network"

#Checks if dataset exists; if not, creates one
if not arcpy.Exists(FDatasetpath):
    if projection.upper() == "Y":
        arcpy.CreateFeatureDataset_management(FGBpath, "Network", nspatialr)
    elif projection.upper() == "N":
        arcpy.CreateFeatureDataset_management(FGBpath, "Network")

#Variable for cable feature class location
FCcablepath = clientpath + "/" + client + ".gdb" + "/Network" + "/cable"

#Checks if cable feature class exists; if not, creates one
if not arcpy.Exists(FCcablepath):
    if projection.upper() == "Y":
        arcpy.CreateFeatureclass_management (FDatasetpath, "cable", "POLYLINE", "", "", "", nspatialr)
    elif projection.upper() == "N":
        arcpy.CreateFeatureclass_management (FDatasetpath, "cable", "POLYLINE")

#Variable for splice point feature class location
FCsplicepath = clientpath + "/" + client + ".gdb" + "/Network" + "/splice_point"

#Checks if splice point feature class exists; if not, creates one
if not arcpy.Exists(FCsplicepath):
    if projection == 'Y' or projection == 'y':
        arcpy.CreateFeatureclass_management (FDatasetpath, "splice_point", "POINT", "", "", "", nspatialr)
    elif projection == 'N' or projection == 'n':
        arcpy.CreateFeatureclass_management (FDatasetpath, "splice_point", "POINT")

exit = raw_input("\n\n File geodatabase, dataset, and the cable \n and splice point feature classes successfully created. \n\n Hit enter to exit.")

J'ai encore du travail à faire, comme l'ajout des champs nécessaires.

ianbroad
la source

Réponses:

18

La façon dont vous obtenez vos entrées dépend à 100% de qui sera l'utilisateur final, mais vous avez raison, vous ne pourrez pas du tout utiliser raw_input dans ArcMap. Si vous allez être le seul à utiliser le script, il n'y a rien de mal à obtenir vos entrées via raw_input ou des chemins de codage en tant que variables dans votre script. Cependant, si quelqu'un d'autre utilisera le script qui peut ou non avoir une expérience de script, il est préférable d'utiliser getParameterAsText () et d' implémenter votre script en tant qu'outil de script dans ArcMap. La création d'un outil de script donnera à l'utilisateur une interface similaire à celle utilisée par la plupart des outils ESRI (tels que les outils standard comme le tampon, etc.).

Une chose à souligner est que la façon dont vous avez conçu vos raw_inputs crée une interaction étape par étape entre l'utilisateur et le script. Si cela est exécuté à l'aide de getParameterAsText () dans ArcMap, l'étape par étape disparaîtra et ce ne sera qu'une série de paramètres qui sont entrés avant d'exécuter le script.

L'automatisation est l'un des principaux objectifs des scripts. Si vous comptez l'exécuter sur plusieurs jeux de données, vous devez vérifier les boucles . Si vous êtes allé si loin, vous en avez probablement lu au moins, mais à titre d'exemple sur la façon dont vous pouvez les utiliser: supposons que vous ayez plusieurs jeux de données sur lesquels vous devez effectuer la même opération. Vous pouvez écrire le code des processus à exécuter une fois, puis inclure une boucle «pour» qui prend une liste d'ensembles de données et exécute l'opération sur chacun d'eux.

Pour des choses comme la référence spatiale, vous pouvez `` voler '' une référence spatiale à partir d'un fichier de formes existant en utilisant arcpy.Describe () , ou vous pouvez obtenir une entrée de référence spatiale en utilisant getParameterAsText () (tant que vous définissez le paramètre comme entrée de référence spatiale lors de la configuration de l'outil de script). L'utilisation de raw_input pour obtenir les noms de chemin est un peu lourde.

bluefoot
la source
4
+1, je passerais définitivement à la prise de paramètres vs raw_input. Peu d'utilisateurs finaux voudront utiliser une interface de ligne de commande par rapport à une interface graphique, en particulier lorsqu'ils sont habitués à quelque chose comme les outils de géotraitement d'ArcGIS.
blah238
10

En plus des excellentes suggestions de @ egdetti , vous pouvez grandement simplifier votre script en faisant quelques hypothèses au lieu d'écrire la logique if / else pour chaque petite condition.

Par exemple:

  • Au lieu de vérifier si chaque élément existe au préalable, supposez-le simplement et remplacez-le en définissant arcpy.env.overwriteOutput = True. Maintenant, vous pouvez avoir une raison pour laquelle vous devez vérifier au préalable, mais le plus souvent, l'écrasement est très bien.

  • Au lieu de vérifier si l'option de référence spatiale a été définie et d'appeler la même commande de deux manières différentes, passez simplement la variable de référence spatiale à la commande une fois et laissez -la gérer les chaînes nulles ou vides (ce qui ira bien).

  • Utilisez os.path.joinpour joindre des éléments de chemin de fichier au lieu d'utiliser la concaténation de chaînes, qui est lourde de dangers.

    Par exemple au lieu de:

    FGBpath = clientpath + "/" + client + ".gdb"

    Utilisation:

    FGBpath = os.path.join(clientpath, client + ".gdb")
blah238
la source
Impressionnant! Juste le genre de conseils que je cherchais, merci! Connaissez-vous un type de liste qui montre les fonctions / bibliothèques les plus courantes que les gens utilisent? Tels que le os.path.join? Il y en a tellement que c'est un peu écrasant. Je vous attribuerais +1 si je le pouvais. Ils devraient me permettre de voter positivement, mais pas de les réduire!
ianbroad
2
Je suppose que vous avez déjà suivi le didacticiel Python officiel ? Il a des sections pratiques ( 1 , 2 ) sur la bibliothèque standard. Une autre bonne ressource est la liste des modules de la semaine de Doug Hellmann: doughellmann.com/PyMOTW/contents.html
blah238
Aussi, mieux vaut être débordé que débordé, je dis!
blah238
Eh bien, je déteste l'admettre, mais je n'ai pas encore parcouru le tutoriel. J'ai un peu sauté dessus. J'ai pris un cours de C ++ il y a des années, donc je connais en quelque sorte les bases mais j'ai vraiment besoin de lire attentivement le tutoriel. J'ai toujours été un plongeur dans le premier type de personne. Merci pour les liens.
ianbroad
Vous pourriez aussi aimer diveintopython.net , alors :)
blah238