使用python制作ArcGIS插件(2)代码编写

by 李远祥

上一章节已经介绍了如何去搭建AddIn的界面,接下来要实现具体的功能,则到了具体的编程环节。由于使用的是python语言进行编程,则开发者需要掌握一些基本的python编程技能。python部分的知识不是本章节的重点,开发人员可以通过百度及其他方式去获取相关的python知识。ArcGIS在其帮助文档中也为我们提供了一些python的推荐教程,以下灰色文字部分是ArcGIS官方帮助中的一些文字截取。

Python 是一种不受局限、跨平台的开源编程语言,它功能强大且简单易学。因而得到了广泛应用和支持。要了解有关 Python 的详细信息,请访问 python.org。

ArcGIS 9.0 社区中引入了 Python。此后,Python 被视为可供地理处理用户选择的脚本语言并得以不断发展。每个版本都进一步增强了 Python 体验,从而为您提供更多的功能以及更丰富、更友好的 Python 体验。

ESRI 已将 Python 完全纳入 ArcGIS 中,并将其视为可满足我们用户社区需求的语言。下面仅介绍 Python 的部分优势:

  • 易于学习,非常适合初学者,也特别适合专家使用
  • 可伸缩程度高,适于大型项目或小型的一次性程序(称为脚本)
  • 可移植,跨平台
  • 可嵌入(使 ArcGIS 可脚本化)
  • 稳定成熟
  • 用户社区规模大

Python 已延伸到 ArcGIS 中,成为了一种用于进行数据分析、数据转换、数据管理和地图自动化的语言,因而有助于提高工作效率。

了解 Python

以下包含的信息并不是 Python 的语言参考。而是根据一些用于说明如何编写地理处理脚本的示例和概念来介绍某些 Python 语法和行为。

强烈建议您结合相应的 Python 参考书来进一步了解此处介绍的信息。对于 Python 初学者,建议使用以下两本书籍:《学习 Python》(Learning Python)(作者:Mark Lutz 和 David Ascher,出版社:O’Reilly & Associates)和《Python 核心编程》(Core Python Programming)(作者:Wesley J. Chun,出版社:Prentice Hall),这两本书都对该语言进行了详尽介绍,并且内容上不重叠。还有很多其他书籍也介绍了 Python 及其具体用途,其中有些新书会定期出版,因此可以探究可用的内容。Python 网站上提供了 Python 的完整文档,但内容很简明,主要是面向开发人员的。还有一个大型的 Python 在线社区,其中包含很多在线资源,您可通过 Python 主页访问这些资源。

Python 教程

如果您是 Python 的初学者,我们推荐您学习此处列出的一些外部教程。

  • Python 教程 是 Python 文档本身的一部分。
  • 针对非程序员的 Python为编程经验有限的人士提供教程。
  • Python 语言参考介绍 Python 的语法和语义。
针对程序员的 Python 教程

此处所列的外部教程主要面向以前学习过其他编程语言(Perl、Visual Basic、C)的人员。

  • Python 教程是 Python 文档本身的一部分。
  • 针对程序员的 Python为具有其他编程语言经验的人士提供教程。

言归正传,在工程中如何进行编程。首先可以打开工程文件夹中的Instrall目录,用文本编辑器或者其他编辑工具打开.py文件。该py文件已经包含了一些初始化代码了,那我们则需要在事件或者界面初始化中加入适当的脚本即可。下图为设计器自动生成的代码

import arcpy
import pythonaddinsclass ButtonClass5(object):"""Implementation for mytools_addin.button (Button)"""def __init__(self):self.enabled = Trueself.checked = Falsedef onClick(self):passclass ButtonClass6(object):"""Implementation for mytools_addin.button_1 (Button)"""def __init__(self):self.enabled = Trueself.checked = Falsedef onClick(self):passclass ComboBoxClass1(object):"""Implementation for mytools_addin.combobox (ComboBox)"""def __init__(self):self.items = ["item1", "item2"]self.editable = Trueself.enabled = Trueself.dropdownWidth = 'WWWWWW'self.width = 'WWWWWW'def onSelChange(self, selection):passdef onEditChange(self, text):passdef onFocus(self, focused):passdef onEnter(self):passdef refresh(self):passclass ComboBoxClass2(object):"""Implementation for mytools_addin.combobox_1 (ComboBox)"""def __init__(self):self.items = ["item1", "item2"]self.editable = Trueself.enabled = Trueself.dropdownWidth = 'WWWWWW'self.width = 'WWWWWW'def onSelChange(self, selection):passdef onEditChange(self, text):passdef onFocus(self, focused):passdef onEnter(self):passdef refresh(self):pass

可以看到该代码中已经为我们预留了两个combox的事件接口以及两个操作按钮的事件接口。

那么使用什么样的代码编辑器呢,笔者认为可以根据各自的习惯去确定编辑器,个人比较喜欢比较轻量级的NotePad++,可以通过安装python插件来进行python代码的编写。当然,使用windows自带的文本编辑器也是可以编写,但效果不是十分理想。如果希望有代码提示和可调试,可以安装微软的VS2015,安装时选择python编辑器,可以实现Python和ArcPy的代码提示,并且可以对程序进行调试,不过VS2015就比较庞大了。初学者或者简单的应用,不妨可以考虑NotePad++这个轻量级的编辑工具。

首选看到这个py文件中到了两个包,一个是ArcPy,另一个是pythonaddins,这两个都是ArcGIS自己维护的包。其中ArcPy允许我们对ArcGIS的功能进行编写,如ArcMap中所有的工具都能够在

ArcPy中调用,同时ArcPy也会对原始的Python进行了一些简单的封装,将一些特殊的对象封装进去,便于开发。例如双击ArcMap的【裁剪】工具,调出该工具,可以看到其中有【工具帮助】的按钮,如下图所示

点击该按钮,可以进入到该工具的帮助中。帮助里面除了说该工具的使用方法和原理,每个参数的说明之外,还具有ArcPy的调用。如下图

例如该帮助中说明了如何通过arcpy去调用裁剪工具,每一个参数是如何设置的。可以看到,arcpy的调用非常的简洁,而且参数的形式是多样化的,可以是要素类和图层的名称,也可以是直接的获取的变量。关于arcpy的其他介绍,可以参考ArcMap的中文帮助,里面有非常细致的说明,可以帮助我们更加快捷的去设计插件。

用NotePad++打开Install 目录下的.py文件,开始进行编辑。首选需要在说明字符集的问题,我们用到了中文字符,所以,必须在文件最顶出加入gbk字符集。然后需要定义一些变量,例如用作记录存储路径,裁剪数据,裁剪的图层等,如下代码

#coding=gbk
import arcpy
import pythonaddinsclass AB:workPath=""     #记录保存路径listLayer=[]    #需要裁剪的图层列表ClipFeat=""     #用作裁剪的图层

这里定义了一个类,用作记录一些基本的信息,这些变量会在后面分别给予赋值。

接下来我们来看下来项怎么设置。插件的设想是在mxd里面获取一个图层作为裁剪用的范围图层,当然,这个图层是必须要先做好并加载到mxd中,combox的作用就是指定这个图层。但至于是哪个图层,那就需要先获取到地图文档中所有的图层,然后提供下拉列表。在列表中选中图层后,则将这个图层赋值给AB类的ClipFeat变量。这也是常规的编程做法了。看下面代码是怎么实现的。Combox已经定义后一些列的事件了,我们分别在事件里面加入python代码。

class ComboBoxClass1(object):   #选择用于裁剪的图层"""Implementation for mytools_addin.combobox (ComboBox)"""def __init__(self):mxd = arcpy.mapping.MapDocument('current')df = arcpy.mapping.ListDataFrames(mxd, "图层")[0]for lyr in arcpy.mapping.ListLayers(mxd,"",df):AB.listLayer.append(lyr.name)self.items = AB.listLayerself.editable = Trueself.enabled = Trueself.dropdownWidth = 'WWWWWW'self.width = 'WWWWWW'def onSelChange(self, selection):AB.ClipFeat = selectionprint AB.ClipFeatpassdef onEditChange(self, text):passdef onFocus(self, focused):passdef onEnter(self):passdef refresh(self):pass

上述代码可以看到,在combox的初始化中,利用arcpy.mapping的方式获取mxd文档中所有的图层,并将这些图层加入到AB类的listLayer数组中,用数组来记录这些图层,然后将这个数组赋值给combox的items,这样就能在combox中看到这个mxd的所有图层了。

onSelChange 事件是用来响应选择操作的,在这个combox中,需要从mxd里面选择一个图层来用作指定裁剪范围,可以看到,直接将选中的值赋值给 AB.ClipFeat。其他事件就不需要再给代码了。从这个例子可以看到,python就像积木一样,将arcgis的一些功能快速的堆积在一起,这就是我们选择使用python做开发的原因。

第二个combox是用于现实裁剪后的数据保存的路径。由于设计器中没有给出toolbox上的label或text控件,所以,只能使用combox来现实我们选择的保存路径。这个combox就什么都不用做,保留原来的代码就行了。我们会在选择后路径后会给予它路径值作为现实,其原始代码如下

class ComboBoxClass2(object):  #用于现实路径#用于显示路径"""Implementation for mytools_addin.combobox_1 (ComboBox)"""def __init__(self):self.editable = Trueself.enabled = Trueself.dropdownWidth = 'WWWWWW'self.width = 'WWWWWW'def onSelChange(self, selection):passdef onEditChange(self, text):passdef onFocus(self, focused):passdef onEnter(self):passdef refresh(self):pass

接下来就是在选择路径的按钮下弹出选择文件夹或者gdb的路径了(fileGDB也是个文件夹)。如果是选择到文件级别,那保存的数据就是shapefile,如果选择的文件夹刚好是fileGDB,arcpy则会自动将数据保存到gdb中去,这一点是非常人性化的,不需要些代码去识别和控制到底是文件夹还是gdb,更不用去控制导出的数据格式。看以下代码

class ButtonClass5(object):#选择存储的路径"""Implementation for mytools_addin.button (Button)"""def __init__(self):self.enabled = Trueself.checked = Falsedef onClick(self):AB.workPath=pythonaddins.OpenDialog("选择存储路径")ComboBoxClass2.items=[AB.workPath,'']pass

在onclick事件中,使用 pythonaddins.OpenDialog 来打开windows路径选择器,这些界面操作都由pythonaddins 包实现了,我们只需要简单调用就行,选中路径后将路径赋值给A B.workPath ,先记录下来。然后不忘初衷的是,在 ComboBoxClass2.items 中显示指定的路径。

前面的这些代码都没能实现裁剪,都是一些交互性的脚本代码,那接下来这个裁剪功能才是核心的。在点击之行按钮后,我们需要调用裁剪功能去进行批量裁剪。那么,涉及到裁剪的各个变量,我们都已经在上述的交互中完成。来看看批量裁剪的功能,就是利用ClipFeat对listLayer每一个元素进行裁剪操作,并将结果保存在workpath中,命名的方式与图层名保持一致。

class ButtonClass6(object):#执行最终的操作"""Implementation for mytools_addin.button_1 (Button)"""def __init__(self):self.enabled = Trueself.checked = Falsedef onClick(self):mxd = arcpy.mapping.MapDocument('current')df = arcpy.mapping.ListDataFrames(mxd, "图层")[0]for lyr in arcpy.mapping.ListLayers(mxd,"",df):outStr=u'正在裁剪'+lyr.name+u'...'resultFeats = AB.workPath+"/"+lyr.namearcpy.analysis.Clip(lyr.dataSource, AB.ClipFeat,resultFeats) #核心代码print "裁剪结束"pass

可以看到,非常核心的裁剪代码就是arcpy.analysis.Clip 功能,这个功能就是我们上面说的toolbox工具箱里面的工具,早已经在arcgis里面实现,只需要一个语句进行调用即可。关键的部分我们使用了for循环来实现遍历,做成了批量裁剪。与toolbox工具里面的批量处理不一样的是,这个批量裁剪的工具裁剪出来的名称可以有我们自己来处理,这就避免了所有的结果带_clip的后缀。

下面来看这个工具的所有代码,非常简介的几行代码实现了一个简单而实用的工具。

#coding=gbk
import arcpy
import pythonaddinsclass AB:workPath=""     #记录保存路径listLayer=[]    #需要裁剪的图层列表ClipFeat=""     #用作裁剪的图层class ButtonClass5(object):#选择存储的路径"""Implementation for mytools_addin.button (Button)"""def __init__(self):self.enabled = Trueself.checked = Falsedef onClick(self):AB.workPath=pythonaddins.OpenDialog("选择存储路径")ComboBoxClass2.items=[AB.workPath,'']passclass ButtonClass6(object):#执行最终的操作"""Implementation for mytools_addin.button_1 (Button)"""def __init__(self):self.enabled = Trueself.checked = Falsedef onClick(self):mxd = arcpy.mapping.MapDocument('current')df = arcpy.mapping.ListDataFrames(mxd, "图层")[0]for lyr in arcpy.mapping.ListLayers(mxd,"",df):outStr=u'正在裁剪'+lyr.name+u'...'resultFeats = AB.workPath+"/"+lyr.namearcpy.analysis.Clip(lyr.dataSource, AB.ClipFeat,resultFeats) #核心代码print "裁剪结束"passclass ComboBoxClass1(object):   #选择用于裁剪的图层"""Implementation for mytools_addin.combobox (ComboBox)"""def __init__(self):mxd = arcpy.mapping.MapDocument('current')df = arcpy.mapping.ListDataFrames(mxd, "图层")[0]for lyr in arcpy.mapping.ListLayers(mxd,"",df):AB.listLayer.append(lyr.name)self.items = AB.listLayerself.editable = Trueself.enabled = Trueself.dropdownWidth = 'WWWWWW'self.width = 'WWWWWW'def onSelChange(self, selection):AB.ClipFeat = selectionprint AB.ClipFeatpassdef onEditChange(self, text):passdef onFocus(self, focused):passdef onEnter(self):passdef refresh(self):passclass ComboBoxClass2(object):  #用于现实路径#用于显示路径"""Implementation for mytools_addin.combobox_1 (ComboBox)"""def __init__(self):self.editable = Trueself.enabled = Trueself.dropdownWidth = 'WWWWWW'self.width = 'WWWWWW'def onSelChange(self, selection):passdef onEditChange(self, text):passdef onFocus(self, focused):passdef onEnter(self):passdef refresh(self):pass

代码实现完后,确保没有问题,记得重新执行一下工程目录下的makeaddin.py 脚本,生成一个新的esriaddin文件。在安装这个新的插件之前,需要先在加载项管理器中删除原来的插件,再重新安装这个新的插件。直到这一步为止,这个插件基本就实现完成了。如果想更进一步,那就在执行完之后将mxd里面的所有图层的数据源设置为裁剪后的数据源,这样就实现所见即得的结果了。

插件源码和测试数据下载地址链接:http://pan.baidu.com/s/1i58tewX 密码:3cv3

使用python制作ArcGIS插件(2)代码编写相关推荐

  1. arcgis python工具-使用python制作ArcGIS插件(1)工具介绍

    使用python制作ArcGIS插件(1)工具介绍 by 李远祥 ArcGIS从10.0开始支持addin(ArcGIS软件中又叫作加载项)的方式进行插件制作.相对于以往9.x系列,addin的无论是 ...

  2. 使用python制作ArcGIS插件(3)ArcPy的使用说明

    使用python制作ArcGIS插件(3)ArcPy的使用说明 by 李远祥 ArcPy 是一个以成功的 arcgisscripting 模块为基础并继承了 arcgisscripting 功能进而构 ...

  3. 使用python制作ArcGIS插件(1)工具介绍

    使用python制作ArcGIS插件(1)工具介绍 by 李远祥 ArcGIS从10.0开始支持addin(ArcGIS软件中又叫作加载项)的方式进行插件制作.相对于以往9.x系列,addin的无论是 ...

  4. 使用python制作ArcGIS插件(5)其他技巧

    使用python制作ArcGIS插件(5)其他技巧 by 李远祥 使用python做插件开发,除了了解ArcToolBox工具之外,还需要在了解ArcPy的相关函数和接口.只有掌握了这些,才可以顺利的 ...

  5. 使用python制作ArcGIS插件(4)界面交互

    使用python制作ArcGIS插件(4)界面交互 by 李远祥 插件界面部分,除了一开始在设计器中设计的这些界面元素之外,还可以与操作系统进行一些输入输出的交互,这部分的实现全部在pythonadd ...

  6. python使用rpa需要什么插件_使用Python制作ArcGIS插件基础篇——工具介绍

    ArcGIS从10.0开始支持addin(ArcGIS软件中又叫作加载项)的方式进行插件制作.相对于以往9.x系列,addin的无论是从使用或者编写都更加方便快捷.通过开发语言,可以制作ArcGIS ...

  7. pythonarcgis插件_【直播】基于Python开发ArcGIS插件:Python Add-in丨城市数据派

    原标题:[直播]基于Python开发ArcGIS插件:Python Add-in丨城市数据派 Add-in是什么? Add-in(加载项)是一种自定义项(例如工具栏上的工具集合),Add-in可以插入 ...

  8. python in arcgis_【直播】基于Python开发ArcGIS插件:Python Add-in

    活动时间:2020-09-12 ~ 2020-09-12 Add-in是什么? Add-in(加载项)是一种自定义项(例如工具栏上的工具集合),Add-in可以插入到 ArcGIS Desktop 应 ...

  9. python制作浏览器插件_分享一个火车浏览器脚本插件python中文分词

    最近在采集一批信息,发现火车浏览器的自带分词插件,分词效果不是很理想,在网上找了一个API分词接口:pullword 其实对于火车浏览器脚本插件用PHP和python都可以写,之前做了一个PHP分词插 ...

最新文章

  1. ssh反向主动连接 及脚本加密
  2. Linux 重新挂载分区的方法
  3. tornado连接数据库
  4. HDU 4332 Constructing Chimney [状态压缩+矩阵]
  5. 现代软件工程 作业汇总
  6. not supported between instances of 'SafeText' and 'int' 问题出现以及解决
  7. GitHub 版本控制 项目托管 04 创建GitHub远程仓库
  8. MySQL:由USE DB堵塞故障引发的思考
  9. php openssl des ecb,php7.2 des-ede3-ecb加密报错:openssl_encrypt():Unknown cipher algorithm 落叶随风博客...
  10. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-3.热部署在Eclipse和IDE里面的使用...
  11. Project 3 :Python爬虫源码实现抓取1000条西刺免费代理IP-HTTPS并保存读取
  12. 马尔科夫区制转换matlab,马尔科夫区制转移混频向量自回归(MS-MF-VAR)模型及其Gauss实现...
  13. js文档模式之混杂模式与标准模式
  14. “单细胞”中研究APC/CCDH1失活调控细胞周期起始的分子机制
  15. python web flask 插件_Python WEB框架之Flask
  16. 第4.1章 飞鸟集爬虫采用结巴分词随机排序存储
  17. B端大数据量查询优化方案
  18. 003-photoshop快速去掉图片背景颜色、签名放到指定文档合成图片
  19. vue——echarts更换主题
  20. .msi文件安装报错

热门文章

  1. android edittext drawable,android – 在事件上显示复合drawable到EditText
  2. redis数据丢失_Redis持久化Redis宕机或者出现意外删库导致数据丢失解决方案
  3. python 保留顺序去重_Python入门很简单,只要掌握3456点
  4. 建立计算机科学系的学生视图,SQL语句练习及答案
  5. Vue packages version mismatch:- vue@2.6.14 - vue-template-compiler@2.6.11解决方法
  6. git 创建和修改ssh_key
  7. 微信退款异步通知解密异常-填充无效,无法被移除
  8. ReactNative字体大小不随系统字体大小变化而变化
  9. 整理了js数组去重4种方法
  10. Python版本微信跳一跳,软件配置