Comment désactiver et activer le dessin dans ArcMap à l'aide de Python?

13

Le script que j'écris repositionne deux blocs de données et définit leur étendue.

Ce faisant, il redessine l'intégralité d'Active View 4 fois, ce qui ralentit considérablement le script.

En appuyant sur F9 ou en cliquant sur le bouton «Suspendre le dessin» avant d'exécuter le script, vous désactivez le dessin et accélérez l'exécution du script, mais je souhaite que le script le fasse automatiquement.

Je souhaite désactiver le dessin ArcMap 10 au début du script et l'activer à la fin.

Comment puis-je faire cela?

Tanneur
la source

Réponses:

13

Je n'ai rien vu de natif dans ArcPy. La chose la plus simple à faire est probablement d'envoyer la séquence de touches F9 à la fenêtre ArcMap à l'aide du module SendKeys .

J'ai testé avec cette syntaxe et cela a bien fonctionné:

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

La seule mise en garde est que vous devrez peut-être décocher "Toujours exécuter au premier plan" dans l'onglet Général des propriétés du script. Sinon, la séquence de touches risque d'être interceptée par la fenêtre de progression du script.

Evan
la source
Merci! J'ai quand même une question. N'importe quel ordinateur de notre réseau devra pouvoir utiliser ce script. Est-il possible d'héberger le module SendKeys sur notre serveur afin de ne pas avoir à l'installer sur chaque ordinateur? Je ne suis pas familier avec l'ajout de nouveaux modules
Tanner
1
Vous pouvez utiliser PYTHONPATH pour ajouter aux répertoires par défaut que Python recherche lors de l'importation de modules. Je ne l'ai jamais utilisé donc je ne peux pas offrir de conseils. Plus d'informations ici: docs.python.org/tutorial/modules.html#the-module-search-path
Evan
Merci. SendKeys fonctionne lorsque je désactive «Toujours exécuter au premier plan», mais le problème est qu'un outil de script doit s'exécuter au premier plan si vous utilisez arcpy.mapping.MapDocument («Actuel») Je me demande s'il existe un moyen de le faire dans ArcObjects? Là encore, je n'ai jamais utilisé ArcObjects
Tanner
1
Vous pouvez modifier l'outil lui-même pour qu'il s'exécute toujours au premier plan à partir de la boîte de dialogue des propriétés de l'outil de script.
Jason Scheirer
Ce lien vers le module SendKeys ne fonctionne pas pour moi. Quelqu'un d'autre a des problèmes avec ça? Avez-vous un autre lien pour télécharger ce module?
user3697700
6

Je me rends compte que cette question a été fermée il y a longtemps, mais j'ai de vieux outils pour lesquels c'était récemment un problème et la solution SendKeys ne semble plus fonctionner, j'ai donc roulé ma propre solution après avoir expérimenté. Il ne désactive pas le dessin, mais crée l'équivalent de performance en désactivant les couches et en les réactivant une fois terminé. L'exécution du script en arrière-plan ne résout pas le problème (même si je le pensais), j'ai donc essayé de désactiver toutes les couches - et cela a fonctionné! Accélération complète vers le code équivalent dans un document vide. Voici donc du code pour y parvenir.

Ces deux fonctions, lorsqu'elles sont combinées, désactivent tous les calques d'un document, retournant l'état enregistré des calques. Ensuite, lorsque vos opérations sont terminées, vous pouvez les réactiver en fournissant cet état enregistré à la deuxième fonction. Utilisation recommandée:

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)

Et les fonctions sont ci-dessous - corrections, commentaires, etc. bienvenue - code assez nouveau donc il peut avoir quelques bugs, mais il en a été testé.

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
la source