Tuesday, 9 June 2015

arcpy - Python scripts that run inside ArcMap vs ones that run outside?



I'm just starting to get into Python scripting for work.


I'm currently creating a script to automate a process.


Basically, it asks the user the client name, gets a projection if available, creates directory on C: drive for client, creates file geodatabase specific to client, creates required dataset, and creates feature classes specific to clients data. Eventually, it will also add the required fields to each feature class and probably some other things.


I started this not really knowing the proper etiquette of Python scripting for ArcMap. But what I've created so far will only run outside ArcMap I believe.


Is this acceptable?


Instead of getting user input through arcpy.getparamaterastext(), which I just found out about, I'm using raw_input().


Is this okay?


It does work, I'm just not sure if this is a proper way to do scripting.


Here's the code I have so far.


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.")

I still have some work to do, like adding the needed fields.



Answer



How you get your inputs depends 100% on who the end user will be, but you're right, you won't be able to use raw_input in ArcMap at all. If you are going to be the only one using the script, there's nothing wrong with getting your inputs through raw_input, or hard coding paths as variables into your script. However, if anyone else will be using the script that may or may not have any scripting experience, it is best to use getParameterAsText() and implement your script as a script tool in ArcMap. Creating a script tool will give the user an interface that is similar to the one used by most ESRI tools (such as standard tools like buffer, etc...).


One thing to point out is that the way you have your raw_inputs designed creates a step by step interaction between the user and the script. If this is run using getParameterAsText() in ArcMap, the step by step will go away, and it will just be a series of settings that are input prior to running the script.


One of the main purposes for scripting is automation. If you are going to be running this on multiple datasets, you should check out loops. If you've come this far, you've probably read about them at least, but as an example for how you could use them: say you have multiple datasets that you need to perform the same operation on. You can write the code for the processes that need to be accomplished once, then include a 'for' loop that takes a list of datasets and performs the operation on each of them.



For things like spatial reference, you can 'steal' a spatial reference from an existing shapefile using arcpy.Describe() , or you can get a spatial reference input using getParameterAsText() (as long as you define the parameter as a spatial reference input when setting up the script tool). Using raw_input to get path names is a bit cumbersome.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...