Skip to main content

使用 Python 脚本进行创作

在您的计算机上成功运行的大多数 Python 脚本工具将作为 ArcGIS Enterprise 上的 Web 工具或者独立 ArcGIS Server 上的地理处理服务成功发布并运行 - 您无需修改​​脚本。

构造工程数据的路径

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

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

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

  • 地图或场景内容列表中的图层

  • 文件夹

  • 文件

  • 地理数据集,如要素类、地理数据库、地图 (.mapx) 或图层文件 (.lyrx)

在脚本中找到字符串后,可通过测试是否存在数据回答以下问题:

  • 字符串指的是内容窗格中的图层吗?

  • 字符串中是否包含数据的绝对路径(如 "e:\Warehousing\ToolData\SanFrancisco.gdb\streets")?

  • 字符串是否引用了可以相对于已知位置(如工程文件 .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.management.CopyFeatures(os.path.join(prj.defaultGeodatabase, "study_sites"),
                           "memory/tempSite")
# Create a variable to reference the LYRX folder
lyrxFolder = os.path.join(prj.homeFolder, "LYRXs")
arcpy.management.ApplySymbologyFromLayer("memory/tempSite",
                                      os.path.join(lyrxFolder, "Site4.lyrx"))

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

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

将图层引用为工程数据

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

Python 脚本工具中使用的图层

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

注:

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

导入其他 Python 模块

您的脚本可能会导入您开发的其他脚本。 例如,以下代码显示了如何导入名为 myutils.py 的 Python 模块,其位于与父脚本相同的目录中且包含一个名为 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 安装的任何模块)进行合并。 您需要确保模块存在且在服务器上正确运行。 这不适用于 numpymatplotlib,以及随默认运行 ArcGIS Server 的联合服务器一起安装的其他模块。 要部署第三方 Python 模块,请参阅为 ArcGIS Server 部署自定义 Python 包

工具验证代码

脚本工具支持自定义工具验证逻辑。 验证支持诸多行为,例如启用和禁用参数、提供默认值和更新字符串关键字。 在没有验证功能的情况下,自定义工具验证逻辑不向 Web 工具客户端提供太多价值。 但是,在具有验证功能的情况下,客户端可以具有与在本地运行工具相似的运行 Web 工具验证体验。

验证功能

当客户端将验证请求发送到 Web 工具或地理处理服务时,将运行 ToolValidator 类。 为了确保工具工具获得更好的体验,仅写入快速处理验证代码。 尽管您可以使用验证代码打开数据集或更改要素或表输入的值或方案,但是验证速度会很慢,并且不会将更改后的要素或表重新发送给 Web 工具用户。

验证功能完全支持以下常用自定义验证。 Python 也支持其他验证功能,更改输入要素、表或栅格值除外。

更新参数过滤器

将根据一个参数值更新另一个参数的过滤器。

def updateParameters(self):
 if self.params[0].value < 1000:
     self.params[1].filter.list = ["A4", "Letter"]
 elif self.params[0].value < 5000:
     self.params[1].filter.list = ["A3", "Tabloid"]
 else:
     self.params[1].filter.list = ["A2", "ANSI C"]
 return

启用或禁用参数

如果第一个参数具有值,则将启用第二个参数;否则,将禁用第二个参数。

def updateParameters(self):
 if self.params[0].value:
     self.params[1].enabled = True
 else:
     self.params[1].enabled = False
 return

更新参数值

如果用户尚未提供参数值,则验证代码会将参数值更新为指定字符串。

def updateParameters(self):
 if not self.params[3].altered:
     self.params[3].value = "Default map authored by " + self.params[2].valueAsText
 return

提供自定义消息

将根据输入的几何类型提供一条消息。

def updateMessages(self):
 self.params[0].clearMessage()
 if self.params[0].valueAsText:
     shapetype = arcpy.Describe(self.params[0]).shapeType.lower()
     if shapetype == "point":
         self.params[0].setWarningMessage("Choosing a point layer may result long running time of the tool.")
     elif shapetype == "polygon":
         self.params[0].setErrorMessage("Polygon inputs are not supported temporarily.")
 return

验证初始化代码

initializeParameters 函数中的这些配置将在工具发布后或在重新启动地理处理服务后影响该工具。

def initializeParameters(self):
 self.params[5].parameterDependencies = [4]
 self.params[7].category = "Detailed configurations"
return

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

验证逻辑使用 Python 实现,并且如同任何其他 Python 脚本一样,将扫描验证代码以查找工程数据和模块。 例如,验证逻辑可能打开非工具参数文件夹:它是在工具验证脚本中使用的工程数据。 适用于 Python 脚本的上述规则在这里也同样适用,c 文件夹会被合并并复制到服务器上(除非在服务器的数据存储中找到该文件夹)。

Python、ArcPy 和脚本工具入门

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

帮助主题

内容

地理处理简介

地理处理的介绍主题。

ArcPy 简介

ArcPy 的介绍主题。

在 Python 中创建工具的快速浏览

什么是脚本工具?

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

设置脚本工具参数

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