ArcGIS Python编程案例(7)-创建自定义地理处理工具

第六章 使用脚本执行地理处理工具 ||| 第八章 数据查询和选择


我们在本章介绍以下案例:

  • 创建一个自定义地理处理工具

引言

除了能够访问ArcGIS提供的系统工具,我们还可以创建自己的自定义工具。这些工具跟系统工具的工作模式相同,也可以在模型构造器,Python窗口以及独立的Python脚本中使用。许多组织机构都会创建自定义工具集来专门处理自己的数据。

创建一个自定义地理处理工具

除了能够在脚本中执行所有可用的工具,你还可以在脚本中调用自己创建的自定义工具。许多自定义工具来专门用于执行组织机构内特定需求的地理处理任务。而且这些工具也很方便共享。

Getting ready

在本案例中,你将学习如何将脚本添加到ArcToolbox下的自定义工具箱中创建自定义地理处理脚本工具。创建自定义脚本工具有很多优点。创建完成后,脚本就变成了地理处理框架中的一部分,也就意味着该脚本可以在模型中,命令行或者其他脚本中使用。另外,脚本也就可以获取ArcMap的环境设置以及帮助文档。同时自定义脚本工具能够提供一个简单易用的用户界面以及容错机制(error-prevention capabilities)。容错机制会提供一个对话框来通知用户工具运行中出现的错误。
ArcToolbox提供的系统工具箱是只读的,不能接受新的工具,因此这些自主开发的脚本工具只能添加到自定义工具箱中。在本案例中,你将会使用一个已编写好的Python脚本,该脚本会从一个逗号分隔符文本文件(comma-delimited text file)中读取野外火情数据,之后将数据转为一个FireIncidents的点要素文件。脚本中需要引用的数据集路径已经过硬编码处理,你需要修改脚本能够接受动态变量的输入。之后将修改后的脚本添加到ArcToolbox中的一个自定义工具中,该工具会为最终用户提供了一个可视化的界面来执行脚本。

How to do it...

你编写的Python地理处理脚本可以添加到ArcToolbox中的自定义工具箱中。你不能将脚本添加到任何一个系统工具箱中,比如AnalysisData Management。不过,你可以创建一个新的自定义工具箱来添加脚本。
1.打开ArcMap创建一个空白的地图文档并打开ArcToolbox窗口。
2.右键单击ArcToolbox内的任何空白位置,选择添加工具箱(Add Toolbox)。在Add Toolbox对话框中,点击New Toolbox按钮。系统会创建一个Toolbox.tbx的工具箱,在下一步中你可以重命名该工具箱:

3.转到C:\ArcpyBook\Ch7文件夹,在该文件夹下创建一个Wildfire Tools的工具箱:

4.选中Wildfire Tools.tbx文件然后点击打开(Open)按钮。如下图所示,该工具箱就出现在ArcToolbox窗口中了:

5.每一个工具箱都需要给定一个名称和别名。别名可以用于唯一识别你的自定义工具。别名应该尽量简短且不包含特殊字符。右键单击新添加的工具箱选择属性(Properties)。如下图所示添加一个wildfire的别名:

你还可以右键单击工具箱选择新建|工具集(New|Toolset)在工具箱中创建一个新的工具集。工具集可以按照功能来对脚本进行分组。在本案例中,你不需要这么做,不过如果在以后需要对脚本进行分组管理时,你就可以通过创建工具集来完成。

6.接下来,我们需要修改InsertWildfires.py脚本文件使其能够接受用户通过ArcToolbox界面提供的动态输入参数。在IDLE中打开C:\ArcpyBook\Ch7\InsertWildfires.py文件。你会看到工作空间路径和包含野火数据的逗号分隔文本文件的路径都是硬编码处理的:

arcpy.env.workspace = "C:/ArcpyBook/data/Wildfires/WildlandFires.mdb"
f=open("C:/ArcpyBook/data/Wildfires/NorthAmericaWildfires_2007275.txt","r")

7.删除以上两行代码。另外,输出要素类名称也是使用硬编码处理:

cur = arcpy.InsertCursor("FireIncidents")

硬编码限制了脚本的灵活性。如果数据集移动或者删除了,脚本也就无法运行。除此以外,硬编码还会让脚本缺少针对不同输入和输出数据集要求的灵活性。在下一步中,我们会移除这些硬编码,让脚本可满足动态输入参数要求。
8.我们会调用arcpy提供的GetParameterAsText()函数来接受用户提供的动态输入参数。如下所示,在try语句下添加以下脚本代码:

try:
    outputFC = arcpy.GetParameterAsText(0)
    fClassTemplate = arcpy.GetParameterAsText(1)
    f = open(arcpy.GetParameterAsText(2),"r")
    arcpy.CreateFeatureclass_management(os.path.split(outputFC)[0],os.path.split(outputFC)[1],"point",fClassTemplate)

你会看到我们调用了Data Management工具箱中的CreateFeatureClass工具,并将outputFC变量和模板要素类(fClassTemplate)变量传递给该工具。该工具将会创建一个包含了用户指定的输出要素类的空要素类文件。
9.你还需要修改一行用于创建插入游标(InsertCursor)对象的代码。如下所示:

cur = arcpy.InsertCursor(outputFC)

10.修改后的完整代码如下:

import arcpy,os
try:
    outputFC = arcpy.GetParameterAsText(0)
    fClassTemplate = arcpy.GetParameterAsText(1)
    f = open(arcpy.GetParameterAsText(2),"r")
    arcpy.CreateFeatureclass_management(os.path.split(outputFC)[0],\
    os.path.split(outputFC)[1],"point",fClassTemplate)    
    lstFires = f.readlines()
    cur = arcpy.InsertCursor(outputFC)
    cntr = 1
    for fire in lstFires:
        if 'Latitude' in fire:
            continue
        vals = fire.split(",")
        latitude = float(vals[0])
        longitude = float(vals[1])
        confid = int(vals[2])
        pnt = arcpy.Point(longitude,latitude)
        feat = cur.newRow()
        feat.shape =pnt.shape
        feat.setValue("CONFIDENCEVALUE",confid)
        cur.insertRow(feat)
        arcpy.AddMessage("Record number: " + str(cntr) + "writen to feature class")
        cntr = cntr + 1
    del feat
    del cur
except:
    print arcpy.GetMessages()
finally:    
    f.close()

接下来,我们将脚本添加到刚刚创建的Wildfire Tools工具箱中。
11.在ArcToolbox中,右键单击之前创建的Wildfire Tools工具箱,选择添加|脚本(Add|Script)。如下图所示弹出添加脚本(Add Script)对话框。填写脚本名称,标签以及描述信息。名称(Name)中不能包含空格以及特殊字符。标签(Label)信息为脚本工具的显示名称。本案例中,标签设置为Load Wildfires From Text文本。最后,添加一些描述信息来说明脚本执行的细节等。
12.名称标签描述的细节信息如下图所示:

13.点击下一步(Next)按钮显示添加脚本的下一个对话框。
14.在该对话框中,你需要制定需要添加到工具中的脚本文件。选择InsertWildfires.py脚本文件。
15.你还需要勾选在进程中运行Python脚本(Run Python Script in process)。在进程中运行脚本会提高脚本执行的速度。

进程外运行Python脚本需要ArcGIS创建一个单独的进程来执行脚本。开启进程和执行脚本的时间会导致脚本运行性能的问题。通常都选择在进程中运行Python脚本。在进程中运行脚本意味着ArcGIS不需要开启第二个进程来运行脚本,脚本与ArcGIS运行在同一个进程中。

16.点击下一步(Next)显示参数窗口,如下图所示:

你在该对话框中输入的每一个参数都要与一个单独的GetParameterAsText()函数调用相关联。在前面,我们已经修改过脚本使其接受通过GetParameterAsText()函数获取的动态参数。该对话框中参数的输入的顺序应该与脚本中指定接受的顺序一致。比如,你在脚本中插入了下面的代码:

outputFC = arcpy.GetParameterAsText(0)

那么你在参数对话框中添加的第一个参数就需要与该行代码关联。在脚本中,outputFC参数代表运行脚本后创建的要素类。你通过点击显示名称(Display Name)下的第一行来添加参数。你可以在该位置输入任意文本,该文本会显示给用户。你还需要选择与该参数相关联的数据类型。在本案例中,数据类型(Data Type)应该选择要素类(Feature Class)。每一个参数都有一些属性可以设置。其中比较重要的属性包括类型(Type)方向(Direction)以及默认值(Default)
17.如下图所示在对话框中输入输出要素类的信息。确保方向(Direction)属性设置为Output

18.接下来,我们需要添加一个作为输出要素类属性模板的要素类参数。如下图所示输入信息:

19.最后,我们还需要添加一个指定逗号分隔符文本文件的参数,该文本文件用于创建要素类的输入参数。如下图所示输入信息:

20.点击完成(Finish)按钮。如下图所示,一个新的脚本工具就会添加到Wildfire Tools工具箱中:

21.现在我们来测试工具是否可用。双击脚本工具弹出如下图所示对话框:

22.定义一个输出要素类文件。点击打开文件图标找到C:\ArcpyBook\data\Wildfires中的WildlandFires.mdb个人数据库。
23.你还需要指定一个输出要素类的名称。在本案例中,我们将输出要素类命名为TodayWildfires,当然你可以命名为你喜欢的名称。点击保存(Save)按钮。

24.对于属性模板,你需要指向已经创建好的FireIncidents要素类。该要素类包含了一个CONFIDENCEVAL的字段,该字段也会在输出要素类中创建。点击浏览(Browse)按钮,选择C:\ArcpyBook\data\Wildfires\WildlandFires.mdb中的FireIncidents要素类文件。点击添加(Add)按钮。
25.最后一个参数需要指向一个包含野外火情数据的逗号分隔符文本文件。点击浏览(Browse)按钮,选择C:\ArcpyBook\data\Wildfires中的
NorthAmericaWildfire_2007275.txt文件。点击添加(Add)按钮。
以上参数选择完成后,工具界面如下所示:

26.点击确定(OK)按钮。如下图所示,消息会出现在对话框中。这是一个标准的地理处理工具对话框。如果所有参数设置正确,如下图所示你将看到新的要素类创建完成的提示消息:

如下图所示,新创建的要素类添加到ArcMap显示窗口中:

How it works...

几乎所有的脚本都带有参数,用户需要在工具对话框中提供所需的参数值。工具执行时,参数值传递给脚本。脚本读取这些参数值后在进行处理。Python脚本可以将参数作为输入值。参数可以让脚本接受动态参数值。在这之前,我们所有的脚本都是采用硬编码值。通过指定脚本的输入参数,你就可以在脚本运行时再获取参数值。这一功能让脚本变得更为灵活。
GetParameterAsText()函数用于获取输入参数值,该函数从零值开始索引参数在参数列表中的位置,即第一个参数占据索引位置0。每一个后续参数索引值递增加1。输出要素类是通过读取逗号分隔符文本文件来创建并将其赋值给变量outputFC,该参数通过GetParameterAsText(0)语句获取。使用语句GetParameterAsText(1),我们获取了作为输出要素类属性模板的一个要素类参数。该模板要素类中的字段将会用于定义输出要素类中的字段。最后GetParameterAsText(2)语句会创建一个变量f,该变量用于保存要读取的逗号分隔符文本文件。

There's more...

arcpy.GetParameterAsText()函数并非获取信息传递给脚本的唯一方式。当你从命令行调用Python脚本,你可以传递一组参数(argument)。当向脚本传递参数时,每个参数必须使用空格隔开。这些参数保存在一个基于sys.argv的列表对象中。使用sys.argv引用索引值0来引用列表中的第一个元素,该元素用于保存脚本名称。每一个后续的参数索引值依次递增加1。因此,第一个参数保存在sys.argv[1]中,第二个参数保存在sys.argv[2]。这些参数可以通过脚本来获取。
建议大家使用GetParameterAsText()函数,这是因为前者没有字符数量的限制而后者则要求每个参数要小于1024个字符。不管使用哪种方式,参数读入后,脚本会作为输入值继续执行。


第六章 使用脚本执行地理处理工具 ||| 第八章 数据查询和选择

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容