我们可以在ArcGIS之外调用arcpy站点包运行python独立脚本,从而批量化任务提高工作效率。 如果可以把做好的脚本打包成exe是不是就更方便了呢?想想一键式处理也挺开心的。
Python打包的问题最早是在 ArcGIS知乎 中看到的,有人提问为何打包失败,我还有幸被邀请回答,虽然在这一块我也是小白一枚。 后来,得空时也搜了下相关的资源,虽然大部分人持悲观态度说arcpy不支持打包,但刚好有个帖子说可以实现,并且宣称 “It can be done easily!”,那我就动手试试吧。
Py2exe是一个Python工具发布扩展包,可以用来将Python脚本转化为Windows的可执行程序,详情看 官网 py2exe.org 。
下载Py2exe安装程序,下载地址戳 这里 。
ArcGIS Desktop使用的Python 2.7.x版本,可以对应下载安装 py2exe-0.6.9.win32-py2.7.exe
这个32位的版本;如果你的机器上安装 ArcGIS Desktop 64-bit Background Geoprocessing 补丁或者安装了 ArcGIS Server产品,也可以下载安装 py2exe-0.6.9.win64-py2.7.amd64.exe
。 在这篇博客中,我就以 64位的包为例来说明打包的过程。
打包时需要有至少两个脚本文件,一个是 setup_py2exe.py
, 一个是执行实际任务的 HelloPy2exe.py
脚本文件。
先 看第一个脚本 setup_py2exe.py,包含如下两行:
为了打包时包含arcpy的资源,不要忘记如下options。
options = {"py2exe": {"excludes": ["arcpy"]}}
setup(console=['HelloPy2exe.py'], options=options)
再 来看第二个脚本 HelloPy2exe.py:
path.dirname(interpreter)
可以得到Python解释器(python.exe)的路径,并向 sys.path 添加site-packages目录。
from site import addsitedir
from sys import executable
from os import path
interpreter = executable
sitepkg = path.dirname(interpreter) + "\\site-packages"
print(sitepkg)
addsitedir(sitepkg)
def main():
# 这里编写实际需要执行的任务
if __name__ == "__main__":
print('Start Processing ...')
main()
raw_input("Enter enter key to exit...")
为了简化打包过程,可以事先做个bat文件,放在与上述连个py文件相同的目录:
python setup_py2exe.py.py py2exe
pause
如果提示python不是有效的应用程序,那么python可以使用python.exe的绝对路径(如:C:\Python27\ArcGISx6410.4\python.exe),或者在 windows的环境变量path中添加python.exe所在的路径。
OK, 执行bat文件打包吧。
为了使得exe程序可以使用arcpy的资源,需要在发布后的dist目录中增加 site-packages 文件夹,并增加 *.pth 文件,...\dist\site-packages\Desktop10.4_64bit.pth
。
以64位为例,文件中需要包含如下路径(我的ArcGIS Desktop是默认路径安装的,你要看好自己路径哦):
C:\Program Files (x86)\ArcGIS\Desktop10.4\bin64
C:\Program Files (x86)\ArcGIS\Desktop10.4\ArcPy
C:\Program Files (x86)\ArcGIS\Desktop10.4\ArcToolBox\Scripts
C:\Python27\ArcGISx6410.4\Lib
C:\Python27\ArcGISx6410.4\Lib\site-packages
PS: 开头提到的帖子中,没有提到要增加 C:\Python27\ArcGISx6410.4\Lib 和 C:\Python27\ArcGISx6410.4\Lib\site-packages 这两个路径,我在执行exe时屡屡失败,不得其解。 快要放弃的时候,经过和同事讨论和测试,发现加上这两个路径,找不到 Numpy、Numbers等等包的错误就解决了,开心!
最后,执行exe即可,这个示例中仅对两个数据进行投影变换,后面可以做些更复杂的工作。
arcpy并不是一个免费的站点包,arcpy作为ArcGIS产品的一部分,完全脱离ArcGIS产品是不行的! Import arcpy内部其实会默默地检测产品许可的。 如果你没有产品许可,可能会遇到 “RuntimeError:NotInitialized” 这样的初始化失败的错误。
就现在的测试结果而言,我打包好的exe,放到其他安装有ArcGIS Desktop(64位python需要安装ArcGIS Desktop 64-bit Background Geoprocessing 补丁),ArcGIS Server的机器上都是可以正常运行的。
后面我会再做一些更复杂的测试,有时间的话再放上来。