本节重点介绍了 arcpy.mapping 模块的一些重要使用原则。还针对 arcpy.mapping API 设计提出了一些见解,并就不同情景给出了策略建议。
必须处理现有地图文档或图层文件
arcpy.mapping 模块的设计初衷是用于修改已存在的地图文档 (.mxd) 或图层文件 (.lyr) 中的现有元素。也就是说,它旨在帮助实现现有要素处理的自动化,但不可用于创作新对象。设计的出发点并非想让其成为 ArcObjects 的完全替代品,也不会试图将其用于为 ArcMap 界面中的所有按钮、对话框、菜单选项或快捷菜单项创建函数、方法或属性(这些功能由 ArcObjects 提供)。必须预先在 ArcMap 中认真创作一个含所有相应元素的地图文档或图层文件,然后使用 arcpy.mapping 操作其内容。
以下提供一些 arcpy.mapping 应用的简单示例:
- 替换图层的数据源。
- 遍历一系列数据框范围,查找并替换文本值,然后将页面布局导出至 PDF。
- 通过将 PDF 文档追加到最终产品的方式构建完整的地图册。
引用磁盘上的地图文档或在 ArcMap 中使用 CURRENT 关键字
使用 MapDocument 函数创建 MapDocument 对象有两种不同的方法。第一种,也是首推方法,即提供磁盘上地图文档 (.mxd) 位置的系统路径。该方法最为通用,因为随后可在 ArcGIS 应用程序外部运行脚本。引用磁盘上的特定地图文档这种方法可对脚本执行方式予以更多控制,因为给定脚本在某些地图文档上可能无法正常运行。
第二种方法是将 CURRENT 关键字用作 MapDocumen 函数的输入参数。该方法仅适用于 ArcMap 应用程序内部,因为 MapDocument 对象引用当前加载到 ArcMap 应用程序中的地图文档。想要快速测试和了解 Python 窗口内的脚本功能和命令语法时,使用 CURRENT 会很有帮助。您可以从了解 Python 窗口中的语法入手,然后将那些代码行粘贴到保存在磁盘上的更永久的脚本中。
使用 CURRENT 关键字的脚本工具必须在 ArcMap 内运行(从自定义菜单或目录 窗口)。如果在 ArcCatalog 应用程序内运行使用 CURRENT 的脚本工具,将无法正确执行。出于同样的原因,如果脚本工具含有带 CURRENT 参考的验证脚本,则在您尝试从 ArcCatalog 编辑验证脚本时可能会出现错误。确保在 ArcMap 目录窗口内编辑脚本工具的验证代码。
要使用脚本工具中的 CURRENT 关键字,必须禁用后台处理。后台处理会按照在 ArcGIS 外部运行独立脚本的方式运行所有脚本。为此,启用后台处理时 CURRENT 将不可用。有一个新的脚本工具选项称为始终在前台中运行,可确保脚本工具在前台中运行,即使启用了后台处理也是如此。
添加图层并处理模板地图文档
如上节所述,arcpy.mapping 不允许创作全新的地图文档。按照设计,它也不提供更改现有地图文档的页面大小或方向的功能。解决方案很简单。预先创作含各种相应元素、页面大小、方向等内容的模板地图文档,然后使用 arcpy.mapping 操作其内容。
常见的一种情景是创作一个不含图层的模板地图文档,然后使用 arcpy.mapping AddLayer、AddLayerToGroup 或 InsertLayer 函数向地图文档添加图层。如果图例元素已事先创作为自动将新项目添加到图例,则会自动出现图例项。
另一种常见情景涉及含对开页面的地图册。左侧和右侧页面各偏移一定的距离,以便为装订留出空间。该情景需要有两个地图文档:一个是左侧页面,另一个是右侧页面。使用 Arcpy.mapping 脚本逻辑将所有单个页面合到一起,形成最终的多页 PDF 输出。请参阅创建包含对开页面的地图册,该文档详细介绍了此情景并提供了 arcpy.mapping 代码示例。
创作任何对象时均使用唯一名称
为便于引用地图元素(例如,数据框、图层、布局元素或表)以对其访问和修改,地图元素必须具有唯一名称。许多 arcpy.mapping 列表函数(例如 ListDataFrames、ListLayers、ListLayoutElements 和 ListTableViews)都含有通配符参数,允许您对名称属性进行过滤。这些列表函数始终会返回一个 Python 列表对象。为引用 Python 列表中的地图元素,您可以通过循环遍历列表,也可以在函数末尾追加一个索引号。如果使用通配符并指定唯一名称,则返回的 Python 列表将始终包含一个项目,并可使用索引值 0 对其进行引用。
mxd = arcpy.mapping.MapDocument("CURRENT")
riverLyr = arcpy.mapping.ListLayers(mxd, "Rivers")[0]
titleTxt = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "title")[0]
页面布局元素有一个独立属性,称为元素名称。可在元素的属性 对话框内的大小和位置 选项卡中对其进行设置。
数据框、图层和表不像页面布局元素那样具有独立的名称属性。它们的名称基于内容列表中显示的标注。理想情况下,将为同一地图文档内的所有数据框、图层和表给定唯一名称。如果出现需要有重复名称又不能将二者混淆的情况,那么您需要创作地图文档以使用其他属性进行区分。
以下代码显示了如何使用 Layer 对象的 description 属性对数据框“County Maps”中具有相同名称“Streets”的图层进行区分的示例。
mxd = arcpy.mapping.MapDocument("C:/Project/Project.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "County Maps")[0]
for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.name == "Streets":
if lyr.description == "1:10000":
lyr.visible = True
if lyr.description == "1:100000":
lyr.visible = False
创作额外布局元素并视需要将其移入和移出页面布局
有时可能会遇到这种情况,您在创建地图系列时,其中某些页面具有附加地图元素,例如,额外的数据框、附加图片或文本元素等。这种情况下,您可以创作一个含所有可能布局元素的地图文档,然后根据需要使用 arcpy.mapping 脚本逻辑将这些元素移入和移出页面,而不必专门针对这些情景创作独立的地图文档。如果某个元素被移到页面布局边界以外,则不会将其打印或导出。
在以下示例中,结果布局将基于当前数据框比例显示不同样式的比例尺。如果比例大于 1:25,000,则比例尺单位将以米计。如果比例小于或等于 1:25,000,则比例尺单位将以千米计。
mxd = arcpy.mapping.MapDocument("C:/Project/Project.mxd")
m_scale = arcpy.mapping.ListLayoutElements(mxd, "MAPSURROUND_ELEMENT", "m scale bar")[0]
km_scale = arcpy.mapping.ListLayoutElements(mxd, "MAPSURROUND_ELEMENT", "km scale bar")[0]
df = arcpy.mapping.ListDataFrames(mxd, "Main DF")[0]
if df.scale < 25000:
m_scale.elementPositionX = 5 #on the page
km_scale.elementPostitionX = 15 #off the page
else:
m_scale.elementPositionX = 15 #off the page
km_scale.elementPostitionX = 5 #on the page