通过 Python 模块扩展地理处理

注:

此工作流程需要在 Python 环境中安装 conda、pip、setuptools 和 wheel。默认 ArcGIS Pro Python 环境随附这些包。

通过使用 setuptools 库,可以将 Python 工具箱和自定义工具箱分发给其他 ArcGIS Pro 用户作为 Python 包。构建和分发这些工具箱的过程始于 Python 模块的创建。出于示例的目的,我们将使用 bar.py。

bar.py

bar Python 模块的示例代码。

import os 
 
def hello(): 
    return 'Hello ' + os.getenv('username')

针对分发,模块 bar 将组织到名为 foo 的包中。要构建并分发包,必须存在特定的目录结构。必须创建一个名为 foo 的目录,用于存储 bar 模块。由于分发要求存储 bar 模块的目录位于父目录中,因此需要创建一个名为 src 的目录来保存 foo 目录和 bar 模块。该目录结构将如下所示:

src
└───foo     └  bar.py

要使 bar 模块在导入后即可进行初始化并执行特定代码,其需要 __init__.py 文件。借助 __init__.py 文件,Python 可将 foo 目录视为一个包,并且其他人将能够访问 bar 模块。

__init__.py

foo 中 __init__.py 的示例代码。

from foo import bar

该目录结构现在将为如下所示:

src
└───foo     ├  __init__.py      └  bar.py

通过文件和目录结构,可以使用 bar 导入 import foo 模块并执行 foo.bar.hello() 函数。

下一步是为 foo 包构建分发包,以便将其安装到 Python 站点包目录。由此,其他人即可共享和使用该包。可以通过编写 setup.py 脚本来创建分发包。

setup.py

用于创建 setup.py 脚本的示例代码。

import os from setuptools import setup 
 def read(fname): 
    return open(os.path.join(os.path.dirname(__file__), fname)).read()  
setup(name='foo',       version='1.0', 
      author='Esri',       description=("Example for extending geoprocessing through Python modules"), 
      long_description=read('Readme.txt'),       python_requires='~=3.3', 
      packages=['foo'],       )

setup.py 生成脚本将设置多个属性,并将生成实用工具定向到包目录。详细描述存储在随附的 Readme.txt 文件中。setup.py 和 Readme.txt 文件应位于 src 目录中。有关使用 setup() 的详细信息,请参阅打包和分发工程。该目录结构将如下所示:

Src
├  setup.py
├  Readme.txt
└──foo    ├  __init__.py     └  bar.py
注:

在此过程中,附加 __pycache__ 文件夹可能会显示在相应目录中。这些目录是 Python 生成的已编译版本模块的缓存,用于提高模块的加载速度。为了简化文件夹结构图,此处未显示这些目录。

目录结构就位后,可在 src 目录中使用命令提示符通过运行以下命令来为 foo 包构建安装程序。

python setup.py sdist bdist_wheel

sdist bdist_wheel 命令将在 src 父目录中创建 distbuildfoo.egg-info 文件夹。在 dist 文件夹中,将创建一个名为 foo-1.0-py3-none-any.whl 的 wheel 文件。可以直接通过 pip 来分发 wheel 文件。

使用 pip 安装 wheel 分发

警告:

不建议修改 ArcGIS Pro 默认 Python 环境 (arcgispro-py3),此操作可能会导致意想不到的后果。建议您仅修改克隆环境。

克隆默认 ArcGIS Pro 环境,然后使用 Python 包管理程序切换到克隆环境。

克隆并切换环境后,请打开 ArcGIS Pro Python 命令提示符以直接使用 pip 安装 wheel 文件。Pip 会将 wheel 文件安装到活动环境中。在命令提示符下指向 src\dist 目录,运行以下命令:

pip install foo-1.0-py3-none-any.whl

或者,也可以直接从 build\lib 目录将 foo 目录复制到 %LocalAppData%\ESRI\conda\envs\<environment_name>\Lib\site-packages 文件夹。如果存在禁止运行安装的限制,则从 foo 目录将 build\lib 目录复制到站点包目录所产生的效果将与通过 pip 安装该目录的效果相同,不同之处在于 pip 无法识别或管理该包。

安装 foo 模块或将其复制到站点包目录后,结构将为如下所示:

site-packages
└──foo    ├  __init__.py     └  bar.py

分发 ArcGIS Pro 工具箱作为 Python 包

可以进一步展开此过程以扩展地理处理功能,且将您自己的工具箱显示在 ArcGIS Pro 系统工具箱旁边。您的工具箱的显示和访问方式将与 ArcGIS Pro 内系统工具箱的显示和访问方式相同:可通过地理处理窗口和 arcpy 进行访问。此外,针对消息分发、基于语言的帮助以及对本地化设置的响应,自定义工具箱模块可以利用 ArcGIS Pro 系统工具箱拥有的一套成熟方法。以下为标准目录结构:

Src
├  setup.py
├  Readme.txt
└──foo    ├  __init__.py     ├  bar.py    └──esri        ├──arcpy        ├──help        │   └──gp        │       ├──messages        │       └──toolboxes        └──toolboxes

自定义工具箱(.tbx.pyt)以及所有支持 .py 文件位于 esri\toolboxes 目录中。esri\help\gp 目录中存储着自定义工具箱和工具的工具箱和工具元数据 (.xml)。工具箱的命名约定为 <工具箱别名>_toolbox.xml,各工具的命名约定为 <工具名称>_<工具箱别名>.xml。所有的地理处理消息 (.xml) 文件都放置在 esri\help\gp\messages 目录中。这些消息文件在 Python 工具箱中用于需要进行国际化的消息。工具箱和工具标注类别将覆盖位于 esri\help\gp\toolboxes 目录中的文件。

通过创建名为 SamplePythonToolbox 的 Python 工具箱,可以演示通过 Python 包扩展地理处理的整个过程。

SamplePythonToolbox.pyt

用于创建 Python 工具箱的示例代码:

# -*- coding: utf-8 -*-
import arcpy import os import foo
class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the        .pyt file)."""
        self.label = "Sample Python Toolbox"
        self.alias = "SamplePythonToolbox"
        # List of tool classes associated with this toolbox        self.tools = [SampleTool]
class SampleTool(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "Sample Tool"
        self.description = ""
        self.canRunInBackground = False
    def getParameterInfo(self):
        """Define parameter definitions"""
        parameters=[arcpy.Parameter(displayName='Msg',                                   name='msg',
                                  datatype='GPString',                                  parameterType='Derived',                                  direction='Output')                                  ]        return parameters
    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True
    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal        validation is performed.  This method is called whenever a parameter        has been changed."""
        return
    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool        parameter.  This method is called after internal validation."""
        return
    def execute(self, parameters, messages):
        """The source code of the tool."""
        result = foo.bar.hello()        messages.AddMessage(result + ", welcome to the sample tool")        parameters[0].value = result        return

了解有关创建 Python 工具箱的详细信息

在 SamplePythonToolbox.pyt 工具箱中,foo 包已导入,且 SampleTool 类的 execute 方法已从 bar 模块中调用 hello() 函数。这是将自定义 Python 代码作为包进行分发并通过 ArcGIS Pro 地理处理工具显示其功能的有效方法。创建 SamplePythonToolbox.pyt 后,可以通过在目录窗格的编辑元数据菜单中编辑的元数据为工具箱配置侧面板帮助。

为工具箱创建元数据后,可以运行 arcpy.gp.createtoolboxsupportfiles 函数以生成在上述 esri 文件夹结构内找到的支持 .xml 文件。该命令适用于任何工具箱。将 SamplePythonToolbox.pyt 放在一个单独的暂存文件夹中,然后运行 arcpy.gp.createtoolboxsupportfiles(<path to .tbx or .pyt>)

注:

确保在运行 arcpy.gp.createtoolboxsupportfiles 之前已在工具箱中设置别名。需要使用别名来生成侧面板帮助文件。

esri 文件夹内创建 toolboxes 文件夹,然后将 SamplePythonToolbox.pyt 及其随附的 .xml 文件放在该文件夹中。暂存文件夹现在应如下所示:

Staging
 └──esri
     ├──arcpy
     │   └  SamplePythonToolbox.py
     ├──help
     │   └──gp
     │       ├  SamplePythonToolbox_toolbox.xml
     │       ├  SampleTool_SamplePythonToolbox.xml
     │       ├──messages 
     │       └──toolboxes
     │           └  SamplePythonToolbox.xml
     └──toolboxes
         ├  SamplePythonToolbox.pyt
         ├  SamplePythonToolbox.pyt.xml
         └  SamplePythonToolbox.SampleTool.pyt.xml
注:

arcpy.gp.createtoolboxsupportfiles 不会生成 messages 文件夹;要使脚本工具或 Python 工具箱中使用的错误消息本地化,必须手动创建该文件夹,但是如果没有国际化的计划,则可以省略此操作。

必须将 esri 文件夹从创建该文件夹的暂存目录复制到 src\foo 目录中。现在,用于分发的目录结构将如下所示:

Src
├  setup.py
├  Readme.txt
└──foo    ├  __init__.py     ├  bar.py    └──esri        ├──arcpy        │   └  SamplePythonToolbox.py        ├──help        │   └──gp        │       ├  SamplePythonToolbox_toolbox.xml        │       ├  SampleTool_SamplePythonToolbox.xml        │       ├──messages        │       └──toolboxes        │           └  SamplePythonToolbox.xml        └──toolboxes            ├  SamplePythonToolbox.pyt            ├  SamplePythonToolbox.pyt.xml            └  SamplePythonToolbox.SampleTool.pyt.xml

要在分发中反映这些更改,必须对 setup.py 文件进行修改。

修改后的 setup.py

用于加入 setup.py 目录更改的示例代码:

import os from setuptools import setup 
 def read(fname): 
    return open(os.path.join(os.path.dirname(__file__), fname)).read()  
setup(name='foo',       version='2.0', 
      author='Esri',       description=("Example for extending geoprocessing through Python modules"), 
      long_description=read('Readme.txt'),       python_requires='~=3.3', 
      packages=['foo'],       package_data={'foo':['esri/toolboxes/*',  
                  'esri/arcpy/*', 'esri/help/gp/*',                    'esri/help/gp/toolboxes/*', 'esri/help/gp/messages/*'] 
                  },       )

新 setup.py 与原始 setup.py 中只有一行存在差异,该行将 esri 目录中找到的附加数据添加到包。版本也已增量为 2.0。要更新分发,请在 src 目录中移除 builddistfoo.egg-info 文件夹,然后重新运行 python setup.py sdist bdist_wheel。要进行安装,请从指向 src\dist 目录的命令提示符处运行以下命令:

pip install --upgrade foo-2.0-py3-none-any.whl

现在,在执行并安装 foo 包的构建器后,将在 Python 站点包目录中创建以下目录结构:

site-packages
└──foo    ├  __init__.py     ├  bar.py    └──esri        ├──arcpy        │   └  SamplePythonToolbox.py        ├──help        │   └──gp        │       ├  SamplePythonToolbox_toolbox.xml        │       ├  SampleTool_SamplePythonToolbox.xml        │       ├──messages        │       └──toolboxes        │           └  SamplePythonToolbox.xml        └──toolboxes            ├  SamplePythonToolbox.pyt            ├  SamplePythonToolbox.pyt.xml            └  SamplePythonToolbox.SampleTool.pyt.xml
注:

仅当 messages 文件夹包含文件时,该文件夹才会存在。

现在,在 ArcGIS Pro 中,可以在地理处理窗格中搜索 SamplePythonToolbox,其位于工具箱选项卡中。可以从 arcpy 访问工具箱和工具,如下所示:arcpy.SamplePythonToolbox.SampleTool()

借助 ArcGIS Pro 和 setuptools 库提供的 Python 包开发过程,可以构建并安装包以通过自定义工具箱中的自定义工具来扩展地理处理,可在 ArcGIS 系统工具箱和 arcpy 中查看并执行这些自定义工具箱。这些就是针对英语进行分发所需的全部内容。有关扩展地理处理以使用英语以外的语言进行分发的详细信息,请参阅 Python 模块的国际化

相关主题