Руководство по использованию arcpy.mapping (arcpy.mapping)
В этом разделе представлены важные инструкции по работе с модулем arcpy.mapping. Здесь также описывается процесс разработки API для arcpy.mapping и предлагаются некоторые стратегии для различных сценариев.
Необходимо работать с существующими документами карт или файлами слоев
Модуль arcpy.mapping разработан для изменения существующих элементов в уже существующих документах карты (.mxd) или файлах слоев (.lyr). Другими словами, он помогает автоматизировать существующие объекты, но его нельзя использовать для создания новых объектов. Он не предназначен для полной замены ArcObjects или создания функций, методов или свойств для каждой кнопки, диалогового окна, элемента меню в интерфейсе ArcMap (того, что предоставляет ArcObjects). Необходимо заранее создать документ карты или файл слоя с помощью ArcMap со всеми необходимыми элементами, чтобы можно было применять arcpy.mapping для обработки содержимого.
Далее представлено всего несколько простых примеров использования arcpy.mapping:
- Замена источника данных слоя.
- Итерация по последовательности экстентов фрейма данных, поиск и замена текстовых значений, экспорт компоновки страницы в PDF.
- Создание полного атласа за счет добавления документов PDF в конечный продукт.
Можно внести изменения в существующие документы карты или файлы слоя, а затем сохранить изменения в новом файле с помощью метода saveACopy объекта MapDocument или Layer.
Указание документа карты на диске или использование ключевого слова CURRENT в ArcMap
Существует два способа создания объекта MapDocument с помощью функции MapDocument. Первый и наиболее рекомендуемый метод – указание системного пути к расположению документа карты (.mxd) на диске. Этот способ наиболее универсален, так как такой скрипт можно будет запускать вне приложения ArcGIS. Указание ссылки на документ карты на диске предоставляет больше возможностей для управления с точки зрения запуска скрипта, так как данный скрипт может работать не со всеми документами карты.
Второй способ – использование ключевого слова CURRENT в качестве входного параметра функции MapDocument. Этот метод работает только в приложении ArcMap, так как объект MapDocument ссылается на документ карты, загруженный в данный момент в приложение ArcMap. Использование CURRENT очень полезно при быстром тестировании и изучении возможностей скриптов и синтаксиса команд в окне Python. Можно приступить к изучению синтаксиса в окне Python, а затем вставлять эти строки кода в скрипты, сохраняемые на диск.
Инструменты скрипта, использующие ключевое слово CURRENT, должны запускаться из ArcMap (из пользовательского меню или окна Каталога) . Инструмент скриптов, использующие CURRENT, будут работать неправильно при запуске из приложения ArcCatalog. По этой же причине, если у инструмента есть скрипт проверки со ссылкой на CURRENT, при попытке изменения скрипта проверки в ArcCatalog может возникнуть ошибка. Обязательно измените код проверки в окне Каталога ArcMap.
Чтобы использовать ключевое слово CURRENT в инструменте на основе скрипта, необходимо отключить фоновую обработку. При фоновой обработке все скрипты выполняются так, будто автономные скрипты за пределами приложения ArcGIS, поэтому CURRENT не будет работать с включенной фоновой обработкой. Доступна новая опция для инструмента-скрипта, Всегда выполнять не в фоновом режиме (Always run in foreground), которая гарантирует, что инструмент будет всегда работать в активном режиме, даже если включена фоновая обработка.
Добавление слоев и работа с шаблонами документов карты
Как было указано в предыдущем разделе, arcpy.mapping не позволяет полностью создавать новые документы карты. Этот модуль также не предназначен для изменения размера или ориентации страницы существующих документов карты. Выход из ситуации прост. Заранее создайте шаблоны документов карты со всеми необходимыми элементами, размерами и ориентацией страниц, чтобы можно было применять arcpy.mapping для обработки содержимого.
Распространенным сценарием является создание шаблона документа карты без слоев и последующее использование функций AddLayer, AddLayerToGroup и InsertLayer модуля arcpy.mapping для добавления слоев в документ. Если элемент легенды создается заранее для автоматического добавления элементов в легенду, элементы легенды будут отображаться автоматически.
Другой распространенный сценарий касается атласов с разворотами. Левая и правая страницы содержат разные смещения для связывания. В этом сценарии имеется два документа карты: один для левых страниц и другой для правых. Логика скриптов 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]
У элементов компоновки страницы есть отдельное свойство Имя элемента (Element Name). Его можно задать на закладке Размер и положение (Size and Position) в диалоговом окне Свойства (Properties).
У фреймов данных, слоев и таблиц нет отдельного свойства для имени, как и у элементов компоновки страницы. Их имя основано на надписи в таблице содержания. В идеале все фреймы данных, слои и таблицы в одном документе карты должны получать уникальное имя. Если требуется использовать дублирующиеся имена, но иметь возможность изолировать одно от другого, необходимо создать документ карты так, чтобы эти имена можно было отличать с помощью других свойств.
Ниже представлен пример кода, показывающий, как слои с одинаковым именем 'Streets' в одном фрейме данных 'County Maps' могут быть изолированы с помощью свойства description объекта Layer.
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