使用 Python 脚本创作 web 工具

抢先版本:

在您的计算机上成功执行的大多数 Python 脚本工具都会作为 web 工具成功发布并执行 - 您不需要以任何方式修改脚本。 但是,如果您遇到了问题,则可能是因为您的脚本使用了大量工程数据或在导入您开发的 Python 模块时使用了 import 语句。 针对上述情况,本主题可提供帮助。本主题涵盖以下情况:

  • 如何构造工程数据路径并找到该路径。
  • 如何找到导入模块并使其可用于工具执行。
  • 如何处理第三方库。
  • 如何处理工具验证代码,以及其在客户端和 web 工具之间的交互。

如果您不熟悉 Python、ArcPy 或脚本工具,则可跳到下面的 Python、ArcPy 和脚本工具入门部分,获取有用主题列表。

如何构造工程数据路径并找到该路径

正确构造数据引用路径是许多 Python 脚本的重要组成部分。 这些数据包括脚本内使用的工程数据,以及中间(临时)数据。 存在将数据引用路径写入 Python 的两种不同方式。 有关应如何写入完整路径的详细信息,请参阅设置数据路径

可使用 os.path.join 构造相对于已知位置的数据路径。 这对于构造输出位置位于 in_memory 中的输出位置路径或使用临时位置将临时数据写入磁盘同样有用。 请参阅下方使用 os.path.join 的示例。

当将工具共享为 web 工具时,会对脚本进行扫描,并会对用于 Python 变量或作为函数参数的每个加引号的字符串(无论是单引号还是双引号)进行测试,以查看是否存在现有数据的路径。 在这种情况下,工程数据包括以下内容:

  • 地图或场景目录中的图层
  • 文件夹
  • 文件
  • 地理数据集,如要素类、shapefile、地理数据库、地图 (.mapx) 或图层文件 (.lyrx)

在脚本中找到加引号的字符串后,按如下问题测试是否存在数据:

  1. 字符串指的是内容窗格中的图层吗?
  2. 字符串中包含数据的绝对路径(如 "e:\Warehousing\ToolData\SanFrancisco.gdb\streets")吗?
  3. 是否可以找到相对于已知位置的字符串参考数据,如工程文件 .aprx 或脚本?

这些测试按顺序依次进行。 如果通过测试,数据存在,将会对数据进行合并,但以下情况除外:如果数据已注册到门户的联合数据存储中,则不会对其进行合并。

注:

合并文件夹时,只会复制文件夹中的文件和地理数据库,不会复制子文件夹。 有些地理数据集(例如,文件地理数据库和栅格),从技术上讲它们是文件夹,但它们也是地理数据集,所以也将被复制。 如果文件夹包含图层文件 (.lyrx) 或地图 (.mapx),则图层文件或地图引用的所有数据也将被合并,以使脚本中的任何 arcpy.mp 例程都能够获取对引用数据的访问权限。

提示:

鉴于文件夹的合并方式,您应该避免在文件夹中夹杂一些工具永远用不到的大数据集和文件,因为这会不可避免地增大打包或上传到服务器的数据大小。 (这不适用于位于服务器数据存储中的文件夹,因为这些文件夹不会上传到服务器。)

示例

以下示例基于此工程文件夹结构:

示例工程

数据集和文件夹的相对路径

arcpy.mp 例程可用于获取给定工程的 homeFolderdefaultGeodatabase。 可使用 Python os 模块构建路径。 在以下示例中,使用 LYRXs 文件夹中的图层文件设置并符号化 WebTools.gdb 地理数据库中的要素类:

import arcpy
import os

# The ArcGIS Project is used to build paths from the defaultGeodatabase and 
# homeFolder using os.path.join

# Reference the CURRENT project with ArcGIS Pro open, or point to an .aprx on 
# disk
prj = arcpy.mp.ArcGISProject("CURRENT")
arcpy.CopyFeatures_management(os.path.join(prj.defaultGeodatabase, "study_sites"), 
                              "in_memory/tempSite")

# Create a variable to reference the LYRX folder
lyrxFolder = os.path.join(prj.homeFolder, "LYRXs")
arcpy.ApplySymbologyFromLayer_management("in_memory/tempSite", 
                                         os.path.join(lyrxFolder, "Site4.lyrx"))

在上述代码中,将对 study_sites 要素类和 Site4.lyrx 文件(及其指向的数据)进行测试,以查看引用的数据是否存在。 这些数据集将会合并,然后上传到服务器(除非它们所在的文件夹已被引用为服务器数据存储的一部分)。

lyrxFolder 变量引用了图层文件文件夹的相对路径。 将对此文件夹进行合并;其所有内容(不包括上面提到的子文件夹)将被打包或上传到服务器(除非 lyrxFolder 文件夹属于服务器的数据存储)。

将图层引用为工程数据

将图层用作工程数据,这一并不常见的工作流可能会显著提升 Python 脚本工具的性能。 上述 Python 代码使用了要素类和图层文件的完整路径。 执行 web 工具时,必须先打开数据集,但打开数据集会导致性能损失。 在脚本中使用图层会使数据处于打开和已缓存状态,从而加快执行速度。 下图显示了如何在 Python 脚本中匹配和使用工程内容中的图层:

Python 脚本工具中使用的图层

变量(extentMaskrasterLayer)指向与地图中图层名称相匹配的简单字符串。 将数据共享至门户后,数据将会合并且可用于 web 工具(如果未在数据存储中进行引用),并会将对图层的引用保留在内存中。 从地图中图层到脚本中字符串的名称匹配使工具得以使用图层。

注:

将图层作为内部工程数据在脚本工具中使用时,该脚本工具会成为关联地图的依存对象。 您无法在不显示这些图层的情况下,在其他地图中执行该工具。 此模式会降低脚本工具的常规可移植性。 因此,此模式主要适用于创建 web 工具。

导入其他 Python 模块

您的脚本可能会导入您开发的其他脚本。 例如,以下代码显示了如何导入名为 myutils.pyPython 模块,其位于与父脚本相同的目录中且包含一个名为 getFIDName 的例程:

import arcpy
import myutils

inFeatures = arcpy.GetParameterAsText(0)
inFID = myutils.getFIDName(inFeatures)

遇到 import 语句时,将按照以下顺序定位脚本:

  1. 与脚本相同的文件夹。 如果脚本嵌入到工具箱中,将使用包含工具箱的文件夹。
  2. 系统 PYTHONPATH 变量所引用的文件夹。
  3. 系统 PATH 变量所引用的所有文件夹。
如果在以上某个文件夹中找到要导入的脚本,将会合并脚本。 扫描过程是递归的 - 也会为项目数据扫描导入的脚本,并使用上述全部规则导入。

导入引用模块的另一项技术是使用 sys.path.append 方法。 它可让您设置包含要导入的脚本的文件夹的路径。

import arcpy
import sys
import os

# Append the path to the utility modules to the system path
# for the duration of this script.
myPythonModules = r'e:\Warehousing\Scripts'
sys.path.append(myPythonModules)
import myutils  # A Python file within myPythonModules

在上述代码中,请注意,sys.path.append 方法需要一个文件夹作为参数。 由于 r'e:\Warehousing\Scripts' 是一个文件夹,因此将合并文件夹的全部内容。 复制文件夹内容的规则在此同样适用 - 文件夹中的所有内容(非地理数据集的子文件夹除外)都将被复制。

注:

不会针对工程数据或导入模块扫描文件夹中的 Python 脚本。

第三方模块

不会对第三方模块和库(即不属于核心 Python 安装的任何模块)进行合并。 您需要确保模块存在且在服务器上正确运行。 这不适用于默认随联合的 ArcGIS Server 一起默认安装的 numpymatplotlib 以及其他模块。 要部署第三方 Python 模块,请参阅为 ArcGIS Server 部署自定义 Python

工具验证代码

如果您具有编写脚本工具的经验,则可提供您自己的工具验证逻辑。 Web 工具的客户端不具有执行工具验证逻辑的功能,仅服务器具有该功能。 客户端将其执行任务请求发送到服务时,将在服务器上执行您的验证逻辑。 如果验证例程抛出错误,则任务将停止执行。 如果从服务返回消息,则客户端将接收验证例程抛出的消息。 通常,工具验证代码作为已发布 web 工具的一部分所提供的价值低于在桌面上使用时其为工具提供的价值。 您可能希望使用已减少或移除验证代码的 web 工具的副本并将该副本共享为 web 工具。 您应该在应用程序中开发验证逻辑以使用 web 工具。

通过 Python 实现验证逻辑,并针对工程数据和模块扫描验证代码,就像其他 Python 脚本一样。 例如,您的验证逻辑可能会打开一个包含投影文件 (.prj) 的文件夹(例如 d:\approved_projections),以构建一个客户端在执行工具时可使用的空间参考选择列表。 此文件夹不是工具参数;它是在工具验证脚本中使用的工程数据。 关于 Python 脚本的上述规则在这里也同样适用,结果是 d:\approved_projections 文件夹会被合并、复制到服务器上(除非在服务器的数据存储中找到该文件夹)。

Python、ArcPy 和脚本工具入门

如果您不熟悉 Python、ArcPy 或脚本工具,下表列出的主题将帮助您入门:

帮助主题内容

创建自定义工具快速浏览

创建自己的地理处理工具的基本概念。

什么是 Python

什么是 ArcPy?

Python 和 ArcPy 的介绍主题。 这些主题中包含有关 Python 和 ArcPy 站点包的更详细主题。

Python 中创建工具快速浏览

什么是脚本工具?

有关使用 Python 创建自定义脚本工具的介绍性主题。

设置脚本工具参数

熟悉脚本工具的创建过程后,通常需参阅本主题,本主题详细介绍了脚本工具参数的定义。