Как отключить и включить рисование в ArcMap с использованием Python?

13

Скрипт, который я пишу, перемещает два фрейма данных и устанавливает их экстенты.

При этом он перерисовывает весь Active View 4 раза, существенно замедляя сценарий.

Нажатие клавиши F9 или нажатие кнопки «Приостановить рисование» перед запуском скрипта отключает рисование и ускоряет выполнение скрипта, но я хочу, чтобы скрипт делал это автоматически.

Я хочу отключить рисование ArcMap 10 в начале скрипта и включить его в конце.

Как мне это сделать?

дубильщик
источник

Ответы:

13

Я не видел ничего родного в ArcPy. Возможно, проще всего отправить комбинацию клавиш F9 в окно ArcMap с помощью модуля SendKeys .

Я проверил с этим синтаксисом, и он работал нормально:

import SendKeys
# Send the keystroke for F9
SendKeys.SendKeys("{F9}")

Единственное предостережение в том, что вам может потребоваться снять флажок «Всегда запускать на переднем плане» на вкладке «Общие» свойств скрипта. В противном случае нажатие клавиши может быть зафиксировано окном хода выполнения скрипта.

Evan
источник
Благодарность! У меня есть один вопрос, хотя. Любой компьютер в нашей сети должен иметь возможность использовать этот сценарий. Можно ли разместить модуль SendKeys на нашем сервере, чтобы нам не приходилось устанавливать его на каждом компьютере? Я не знаком с добавлением новых модулей
Таннер
1
Вы можете использовать PYTHONPATH для добавления в каталоги по умолчанию, которые Python просматривает при импорте модулей. Я никогда не использовал это, поэтому я не могу предложить никаких указаний. Более подробная информация здесь: docs.python.org/tutorial/modules.html#the-module-search-path
Эван,
Благодарю. SendKeys работает, когда я отключаю «Всегда запускать на переднем плане», но проблема в том, что инструмент сценария должен запускаться на переднем плане, если вы используете arcpy.mapping.MapDocument ('Current'). Интересно, есть ли способ сделать это? в ArcObjects? Опять же, я никогда не использовал ArcObjects
Tanner
1
Вы можете изменить сам инструмент, чтобы он всегда работал на переднем плане из диалога свойств инструмента Script.
Джейсон Шейрер
Эта ссылка на модуль SendKeys не работает для меня. У кого-то еще есть проблемы с этим? У вас есть еще одна ссылка для загрузки этого модуля?
user3697700
6

Я понимаю, что этот вопрос давно закрыт, но у меня есть несколько старых инструментов, для которых эта проблема была новой, и решение SendKeys, похоже, больше не работает, поэтому я поэкспериментировал со своим собственным решением. Он не отключает рисование, но создает эквивалент производительности, отключая слои и снова включая их, когда закончите. Запуск сценария в фоновом режиме не решает проблему (хотя я думал, что это будет), поэтому я попытался отключить все слои - и это сработало! Полное ускорение до эквивалентного кода в пустом документе. Итак, вот некоторый код для этого.

Эти две функции, когда объединены, отключают все слои в документе, возвращая сохраненное состояние слоев. Затем, когда ваши операции завершены, вы можете включить их снова, передав это сохраненное состояние второй функции. Рекомендуемое использование:

try:
    layer_state = turn_off_all_layers("CURRENT")
    # Do interesting things here
finally:  # put it in a finally block so that if your interesting code fails, your layers still get reenabled
    turn_on_layers("CURRENT", layer_state)

Ниже приведены функции - исправления, комментарии и т. Д. - довольно новый код, поэтому в нем могут быть некоторые ошибки, но некоторые из них были проверены.

def turn_off_all_layers(document="CURRENT"):
    """
        A speedup function for map generation in ArcMap - turns off all layers so that it doesn't try to rerender them while we're using tools (since these tools need
        to run in the foreground and background processesing didn't seem to speed it up).

        Creates a dictionary keyed on the arcpy layer value longName which contains True or False values for whether or not the layers were enabled before running this.
        Allows us to then use turn_on_layers on the same document to reenable those layers

    :param document: a map document. defaults to "CURRENT"
    :return: dict: a dictionary keyed on layer longName values with True or False values for whether the layer was enabled.
    """
    visiblity = {}

    doc = arcpy.mapping.MapDocument(document)
    for lyr in arcpy.mapping.ListLayers(doc):
        if lyr.visible is True:
            try:
                visiblity[lyr.longName] = True
                lyr.visible = False
            except NameError:
                visiblity[lyr.longName] = False  # if we have trouble setting it, then let's not mess with it later
        else:
            visiblity[lyr.longName] = False

    return visiblity


def turn_on_layers(document="CURRENT", storage_dict=None, only_change_visible=True):

    if not storage_dict:
        raise ValueError("storage_dict must be defined and set to a list of layer names with values of False or True based on whether the layer should be on or off")

    doc = arcpy.mapping.MapDocument(document)
    for lyr in arcpy.mapping.ListLayers(doc):
        if lyr.longName in storage_dict:
            if not only_change_visible or (only_change_visible is True and storage_dict[lyr.longName] is True):  # if we're only supposed to set the ones we want to make visible and it is one, or if we want to set all
                try:
                    lyr.visible = storage_dict[lyr.longName]  # set the visibility back to what we cached
                except NameError:
                    arcpy.AddWarning("Couldn't turn layer %s back on - you may need to turn it on manually" % lyr.longName)  # we couldn't turn a layer back on... too bad
nicksan
источник