Jak wyłączyć i włączyć rysowanie w ArcMap za pomocą Pythona?

13

Skrypt, który piszę, umieszcza dwie ramki danych i ustawia ich zakres.

Robiąc to, przerysowuje cały widok Active 4 razy, znacznie spowalniając skrypt.

Naciśnięcie klawisza F9 lub kliknięcie przycisku „Wstrzymaj rysowanie” przed uruchomieniem skryptu wyłącza rysunek i powoduje, że skrypt działa znacznie szybciej, ale chcę, aby skrypt zrobił to automatycznie.

Chcę wyłączyć rysowanie ArcMap 10 na początku skryptu i włączyć go na końcu.

Jak mam to zrobic?

Garbarz
źródło

Odpowiedzi:

13

Nie widziałem nic natywnego w ArcPy. Najłatwiej jest prawdopodobnie wysłać naciśnięcie klawisza F9 do okna ArcMap za pomocą modułu SendKeys .

Testowałem z tą składnią i działała dobrze:

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

Jedynym zastrzeżeniem jest to, że może być konieczne odznaczenie opcji „Zawsze uruchamiaj na pierwszym planie” na karcie Ogólne właściwości skryptu. W przeciwnym razie naciśnięcie klawisza może zostać złapane przez okno postępu skryptu.

Evan
źródło
Dzięki! Mam jednak jedno pytanie. Każdy komputer w naszej sieci będzie musiał korzystać z tego skryptu. Czy można hostować moduł SendKeys na naszym serwerze, abyśmy nie musieli go instalować na każdym komputerze? Nie jestem zaznajomiony z dodawaniem nowych modułów
Tanner
1
Za pomocą PYTHONPATH można dodać do domyślnych katalogów, w których Python szuka podczas importowania modułów. Nigdy tego nie używałem, więc nie mogę zaoferować żadnych wskazówek. Więcej informacji tutaj: docs.python.org/tutorial/modules.html#the-module-search-path
Evan
Dzięki. SendKeys działa, gdy wyłączam „Zawsze uruchamiaj na pierwszym planie”, ale problem polega na tym, że narzędzie skryptowe musi działać na pierwszym planie, jeśli używasz arcpy.mapping.MapDocument („Current”) Zastanawiam się, czy jest jakiś sposób, aby to zrobić w ArcObjects? Z drugiej strony nigdy nie korzystałem z ArcObjects
Tanner
1
Możesz zmienić samo narzędzie, aby zawsze działało na pierwszym planie w oknie dialogowym właściwości narzędzia skryptowego.
Jason Scheirer,
Ten link do modułu SendKeys nie działa dla mnie. Ktoś jeszcze ma z tym problemy? Czy masz inny link do pobrania tego modułu?
user3697700,
6

Zdaję sobie sprawę, że to pytanie zostało zamknięte dawno temu, ale mam kilka starych narzędzi, dla których był to nowy problem, a rozwiązanie SendKeys już nie działa, więc po eksperymentach opracowałem własne rozwiązanie. Nie wyłącza rysowania, ale tworzy równoważną wydajność, wyłączając warstwy i włączając je ponownie po zakończeniu. Uruchomienie skryptu w tle nie rozwiązuje problemu (choć myślałem, że tak), więc spróbowałem wyłączyć wszystkie warstwy - i zadziałało! Pełne przyspieszenie do równoważnego kodu w pustym dokumencie. Oto kod, aby to osiągnąć.

Te dwie funkcje, w połączeniu, wyłączają wszystkie warstwy w dokumencie, przywracając zapisany stan warstw. Następnie, po zakończeniu operacji, możesz je ponownie włączyć, zapewniając zapisany stan drugiej funkcji. Zalecane użycie:

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)

Funkcje są poniżej - poprawki, komentarze itp. Mile widziane - całkiem nowy kod, więc może zawierać pewne błędy, ale niektóre zostały przetestowane.

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
źródło