在ArcMap内部运行的Python脚本与在外部运行的Python脚本?


10

我刚开始使用Python脚本进行工作。

我当前正在创建一个脚本来自动化一个过程。

基本上,它询问用户客户端名称,获取可用的投影,在客户端的C:驱动器上创建目录,创建客户端专用的文件地理数据库,创建所需的数据集,以及创建客户端数据专用的要素类。最终,它还将必填字段添加到每个要素类中,并可能还会添加其他内容。

我开始时并不真正了解ArcMap的Python脚本的正确礼节。但是我相信到目前为止,我所创建的内容只能在ArcMap之外运行。

这可以接受吗?

我使用的是raw_input(),而不是通过我刚刚发现的arcpy.getparamaterastext()获得用户输入。

这个可以吗?

它确实有效,我不确定这是否是编写脚本的正确方法。

这是我到目前为止的代码。

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

我还有一些工作要做,例如添加所需的字段。

Answers:


18

如何获得输入取决于100%的最终用户身份,但是您是对的,您将根本无法在ArcMap中使用raw_input。如果您将成为唯一使用该脚本的人,那么通过raw_input获取输入或将路径作为变量硬编码到脚本中就没有问题。但是,如果其他任何人将使用可能具有或没有任何脚本编写经验的脚本,则最好使用getParameterAsText()并将您的脚本实现为 ArcMap中的脚本工具。创建脚本工具将为用户提供一个界面,该界面类似于大多数ESRI工具(例如缓冲区等标准工具)所使用的界面。

要指出的一件事是,您设计raw_inputs的方式在用户和脚本之间创建了逐步的交互。如果使用ArcMap中的getParameterAsText()运行此命令,那么将逐步删除它,而只是在运行脚本之前输入的一系列设置。

脚本编写的主要目的之一是自动化。如果要在多个数据集上运行它,则应检出loops。如果您走了这么远,您可能至少已经阅读了有关它们的内容,但以使用它们的示例为例:假设您有多个数据集需要对其执行相同的操作。您可以为需要完成一次的过程编写代码,然后包括一个“ for”循环,该循环获取数据集列表并对每个数据集执行操作。

对于空间参考,您可以使用arcpy.Describe()从现有shapefile中“窃取”空间参考,也可以使用getParameterAsText()获取空间参考输入(只要您将参数定义为空间参考输入即可)设置脚本工具时)。使用raw_input获取路径名有点麻烦。


4
+1,我肯定会切换到使用参数vs. raw_input。很少有最终用户想要使用命令行界面而不是GUI,尤其是当他们习惯于ArcGIS的地理处理工具之类的工具时。
blah238

10

除了@egdetti的出色建议之外,您还可以通过做一些假设而不是为每个小情况编写if / else逻辑来大大简化脚本。

例如:

  • 无需事先检查每个项目是否存在,只需假设它存在并通过设置将其覆盖即可arcpy.env.overwriteOutput = True。现在,您可能有某些原因需要进行事先检查,但通常情况下,覆盖是可以的。

  • 而不是检查空间参考选项是否被设置,并调用相同的命令两种不同方式进行,只是空间参考变量传递给一次命令,让处理空或空字符串(它会就好了)。

  • 用于os.path.join联接文件路径元素,而不是使用字符串连接,因为字符串连接充满了危险。

    例如:

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

    采用:

    FGBpath = os.path.join(clientpath, client + ".gdb")

太棒了!只是我一直在寻找的提示,谢谢!您是否知道任何类型的列表,这些列表可以显示人们使用的最常用功能/库?例如os.path.join?有太多的东西使它不堪重负。如果可以的话,我会为您+1。他们应该允许我投票,而不是投票!
ianbroad 2012年

2
我认为您已经完成了官方Python教程?它具有方便的部分(12上的标准库)。另一个很好的资源是Doug Hellmann的“每周模块”列表:doughellmann.com/PyMOTW/contents.html
blah238 2012年

另外,我说,不知所措比不知所措更好!
blah238

好吧,我不想承认这一点,但是我还没有完成本教程。我有点跳进去。几年前,我参加了C ++课程,所以我有点基础知识,但是我确实需要彻底阅读本教程。我向来是第一类人。感谢您的链接。
ianbroad 2012年

你可能会喜欢diveintopython.net过,然后:)
blah238
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.