arcpy.mp 指导原则

本节重点介绍了 arcpy.mp 模块的一些重要使用原则。还针对 arcpy.mp API 设计提出了一些见解,并就不同情景给出了策略建议。

必须使用现有工程或图层文件进行工作

arcpy.mp 模块旨在用于修改现有工程 (.aprx) 或图层文件(.lyr.lyrx)中的现有元素以便实现地图或数据自动化。不能用于在工程中创建或制作大部分对象类型,例如,地图、布局以及图例元素。基本原则是使用该应用程序及其所有功能创建大部分元素,而使用 arcpy.mp 仅自动化那些需要自动化的项。必须预先在该应用程序中认真创作一个含所有相应元素的工程或图层文件,然后使用 arcpy.mp 操作其内容。

下文提供了几个 arcpy.mp 应用的示例:

  • 替换图层的数据源。
  • 遍历一系列范围,查找并替换文本值,然后将页面布局导出至 PDF。
  • 通过将 PDF 文档追加到最终产品的方式构建完整的地图册。
注:

可对现有工程或图层文件执行更改,然后使用 ArcGISProjectLayer 对象上的 saveACopy 方法将这些更改保存至一个新文件。

在磁盘上引用工程或使用 CURRENT 关键字

使用 ArcGISProject 函数引用工程有两种不同的方法。第一种,也是首推方法,即提供磁盘上工程 (.aprx) 位置的系统路径。该方法最为通用,因为随后可在应用程序外部运行脚本。引用磁盘上的特定工程这种方法可对脚本执行方式予以更多控制,因为给定脚本可能无法在所有工程上使用。

提供工程完整路径的示例。

import arcpy
aprx = arcpy.mp.ArcGISProject(r"C:\Projects\YosemiteNP\Yosemite.aprx")

第二种方法是将 CURRENT 关键字作为 ArcGISProject 函数的输入参数。该方法仅适用于该应用程序内部,因为 ArcGISProject 对象引用当前加载到该应用程序中的工程。想要快速测试和了解 Python 窗口内的脚本功能和命令语法时,使用 CURRENT 会很有帮助。您可以从了解 Python 窗口中的语法入手,然后将那些代码行粘贴到保存在磁盘上的更永久的更大脚本中。使用 CURRENT 关键字的脚本工具也必须在应用程序内部运行。

使用 CURRENT 关键字的示例如下。

aprx = arcpy.mp.ArcGISProject('current')

添加图层并处理模板工程

如上节所述,arcpy.mp 不允许完全创作新工程。解决该问题的方案很简单。预先创作含各种相应元素、页面大小、方向等内容的模板工程,然后使用 arcpy.mp 操作其内容。

常见的一种情景是创作一个不含图层的模板工程,然后使用 Map 对象的 addLayeraddLayerToGroup 和/或 insertLayer 方法向工程中的地图添加图层。

另一种常见情景涉及含对开页面的地图册。左侧和右侧页面各偏移一定的距离,以便为装订留出空间。该情景涉及一个工程中有两个布局:一个布局针对左侧页面,另一个布局针对右侧页面。使用 arcpy.mp 脚本逻辑将所有单个页面合到一起,形成最终的多页 PDF 输出。

使用唯一名称创作所有对象

为便于引用布局中的元素以对其进行访问和修改,项目必须具有唯一名称。许多 arcpy.mp 列表函数(例如 listLayoutslistMapslistBookmarkslistTableslistLayerslistLabelClasseslistElements)都含有 wildcard 参数,允许您对名称属性进行过滤。这些列表函数始终会返回一个 Python 列表对象。为引用 Python 列表中的元素,您可以通过循环遍历列表,也可以在函数末尾追加一个索引号。如果使用 wildcard 参数并指定唯一名称,则返回的 Python 列表将始终包含一个项,并可使用索引值 0 对其进行引用。

以下代码显示了使用 name 属性在布局上引用文本元素的示例。

aprx = arcpy.mp.ArcGISProject('CURRENT')
lyt = aprx.listLayouts('Main Attractions')[0]
title = lyt.listElements('TEXT_ELEMENT', 'title')[0]

理想情况下,单个工程中的所有图层和表均应具有唯一名称,但这并不始终可行。如需在地图中具有重复图层和表名称又要使其相互区分,那么您需要制作项目以使用其他属性(如描述属性)对其进行区分。

以下代码显示了如何使用 Layer 对象的 maxThreshold 属性对同一地图 Yosemite National Park 中具有相同名称 Roads 的图层进行进一步区分的示例。这些图层具有相同数据源,但根据查看比例,其绘制方式不同。

import arcpy
aprx = arcpy.mp.ArcGISProject(r"C:\Projects\YosemiteNP\Yosemite.aprx")
mp = aprx.listMaps('Yosemite National Park')[0]
for lyr in mp.listLayers():
  if lyr.name == 'Roads':
     if lyr.maxThreshold == 10000:
        lyr.visible = True
     if lyr.maxThreshold == 100000:
        lyr.visible = False
aprx.save()
del aprx

针对上述示例,可以分别命名每个图层,例如 Roads - large scaleRoads - small scale,这种方法更加方便。

管理布局中元素的可见性

有时可能会遇到这种情况,您在创建地图系列时,其中有些页面需要其他地图元素(如额外的插图、附加图片或文本元素等),但并非所有页面都需要。这种情况下,您可以创作一个含所有可能布局元素的单个布局,然后使用 arcpy.mp 脚本逻辑控制元素的可见性,而不必专门针对这些情景创作独立的布局。可使用两种方法。第一种是根据单个页面和元素配置将元素的 visible 属性设为 TrueFalse。其次,可通过物理方式从页面中移除不需要的元素。可以通过修改 elementPositionXelementPositionY 属性执行此操作。如果元素不在布局中,已将其打印或导出,则不会显示此元素。

在以下示例中,结果布局将基于当前数据框比例显示不同样式的比例尺。如果比例大于 1:25,000,则比例尺单位将以米计。如果比例小于或等于 1:25,000,则比例尺单位将以千米计。

import arcpy
aprx = arcpy.mp.ArcGISProject(r"C:\Projects\YosemiteNP\Yosemite.aprx")
lyt = aprx.listLayouts("Main Attractions")[0]
m_scale = lyt.listElements("MAPSURROUND_ELEMENT", "m scale bar")[0]
km_scale = lyt.listElements("MAPSURROUND_ELEMENT", "km scale bar")[0]
mf = lyt.listElements("MAPFRAME_ELEMENT", "Yose*")[0]
if mf.camera.scale < 25000:
  m_scale.elementPositionX = 5      #Or m_scale.visible = True (on the page)
  km_scale.elementPostitionX = 15   #Or km_scale.visible = False (off the page)
else:
  m_scale.elementPositionX = 15     #Or m_scale.visible = False (off the page)
  km_scale.elementPostitionX = 5    #Or km_scale.visible = True (on the page)
aprx.save()
del aprx

根据情况,应用较为简单的一种方法。例如,如果您更喜欢使用 visible 来控制元素的显示,那么您需要权衡的是,这种方法很难用于管理布局上彼此叠加的多个项。

将脚本作为计划任务运行

您可以使用 Windows 操作系统的“任务计划程序”安排 arcpy.mp 脚本在规定时间运行。

相关主题