Wie deaktiviere und aktiviere ich das Zeichnen in ArcMap mit Python?

13

Das Skript, das ich schreibe, positioniert zwei Datenrahmen neu und legt deren Ausmaße fest.

Dabei wird die gesamte Active View viermal neu gezeichnet, wodurch das Skript erheblich verlangsamt wird.

Wenn Sie vor dem Ausführen des Skripts die Taste F9 drücken oder auf die Schaltfläche "Zeichnung anhalten" klicken, wird die Zeichnung deaktiviert und das Skript wird viel schneller ausgeführt. Ich möchte jedoch, dass das Skript dies automatisch ausführt.

Ich möchte das Zeichnen in ArcMap 10 am Anfang des Skripts deaktivieren und am Ende aktivieren.

Wie mache ich das?

Gerber
quelle

Antworten:

13

Ich habe in ArcPy nichts Natives gesehen. Am einfachsten ist es wahrscheinlich, den F9-Tastenanschlag mit dem SendKeys-Modul an das ArcMap-Fenster zu senden .

Ich habe mit dieser Syntax getestet und es hat gut funktioniert:

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

Die einzige Einschränkung ist, dass Sie in den Skripteigenschaften auf der Registerkarte "Allgemein" möglicherweise die Option "Immer im Vordergrund ausführen" deaktivieren müssen. Andernfalls wird der Tastenanschlag möglicherweise vom Fortschrittsfenster des Skripts erfasst.

Evan
quelle
Vielen Dank! Ich habe jedoch eine Frage. Jeder Computer in unserem Netzwerk muss in der Lage sein, dieses Skript zu verwenden. Ist es möglich, das SendKeys-Modul auf unserem Server zu hosten, damit wir es nicht auf jedem Computer installieren müssen? Ich bin nicht vertraut mit dem Hinzufügen neuer Module
Tanner
1
Mit PYTHONPATH können Sie den Standardverzeichnissen hinzufügen, in denen Python beim Importieren von Modulen sucht. Ich habe das noch nie benutzt, daher kann ich keine Anleitung anbieten. Weitere Informationen finden Sie hier: docs.python.org/tutorial/modules.html#the-module-search-path
Evan
Vielen Dank. SendKeys funktioniert, wenn ich "Immer im Vordergrund ausführen" deaktiviere. Das Problem ist jedoch, dass ein Skript-Tool im Vordergrund ausgeführt werden muss, wenn Sie arcpy.mapping.MapDocument ("Current") verwenden. Ich frage mich, ob es eine Möglichkeit gibt, dies zu tun in ArcObjects? Andererseits habe ich ArcObjects
Tanner
1
Sie können das Tool selbst so ändern, dass es immer im Vordergrund ausgeführt wird.
Jason Scheirer
Dieser Link zum SendKeys-Modul funktioniert bei mir nicht. Hat sonst noch jemand Probleme damit? Haben Sie einen anderen Link zum Herunterladen dieses Moduls?
user3697700
6

Mir ist klar, dass diese Frage vor langer Zeit geschlossen wurde, aber ich habe einige alte Tools, für die dies ein neues Problem war, und die SendKeys-Lösung scheint nicht mehr zu funktionieren. Ich habe meine eigene Lösung nach dem Experimentieren gerollt. Das Zeichnen wird nicht deaktiviert, es wird jedoch die entsprechende Leistung erzielt, indem Ebenen deaktiviert und anschließend wieder aktiviert werden. Wenn das Skript im Hintergrund ausgeführt wird, ist das Problem nicht gelöst (obwohl ich es mir vorgestellt habe), und ich habe versucht, alle Ebenen auszuschalten - und es hat funktioniert! Volle Beschleunigung auf den entsprechenden Code in einem leeren Dokument. Hier ist also ein Code, um das zu erreichen.

Wenn diese beiden Funktionen kombiniert werden, werden alle Ebenen in einem Dokument deaktiviert und der gespeicherte Status der Ebenen wird zurückgegeben. Wenn Ihre Vorgänge abgeschlossen sind, können Sie sie wieder einschalten, indem Sie den gespeicherten Status für die zweite Funktion bereitstellen. Empfohlene Verwendung:

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)

Und die Funktionen sind unten aufgeführt - Korrekturen, Kommentare usw. sind willkommen - ziemlich neuer Code, so dass er einige Fehler aufweisen kann, aber einige getestet wurden.

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
quelle