จะปิดและเปิดใช้งานการวาดใน ArcMap โดยใช้ Python ได้อย่างไร?


13

สคริปต์ที่ฉันเขียน repositions สองเฟรมข้อมูลและตั้งค่าขอบเขตของพวกเขา

เมื่อทำสิ่งนี้ระบบจะวาดมุมมองแอ็คทีฟทั้งหมด 4 ครั้งทำให้สคริปต์ทำงานช้าลงอย่างมาก

การกด F9 หรือคลิกปุ่ม 'หยุดการวาดชั่วคราว' ก่อนที่จะเรียกใช้สคริปต์จะเป็นการปิดใช้งานการวาดและทำให้สคริปต์ทำงานเร็วขึ้นมาก แต่ฉันต้องการให้สคริปต์ทำสิ่งนี้โดยอัตโนมัติ

ฉันต้องการปิดการใช้งานการวาด ArcMap 10 ที่จุดเริ่มต้นของสคริปต์และเปิดใช้งานในตอนท้าย

ฉันจะทำสิ่งนี้ได้อย่างไร

คำตอบ:


13

ฉันไม่เห็นเจ้าของภาษาใน ArcPy สิ่งที่ง่ายที่สุดที่จะทำคือการส่งอาจจะกดแป้น F9 ไปยังหน้าต่าง ArcMap โดยใช้โมดูล SendKeys

ฉันทดสอบด้วยไวยากรณ์นี้และทำงานได้ดี:

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

ข้อแม้เดียวคือคุณอาจต้องยกเลิกการเลือก "ทำงานในเบื้องหน้าเสมอ" บนแท็บทั่วไปของคุณสมบัติสคริปต์ ไม่เช่นนั้นการกดแป้นอาจถูกดักจับโดยหน้าต่างความคืบหน้าของสคริปต์


ขอบคุณ! ฉันมีคำถามหนึ่งข้อ คอมพิวเตอร์ทุกเครื่องในเครือข่ายของเราจะต้องสามารถใช้สคริปต์นี้ได้ เป็นไปได้หรือไม่ที่จะโฮสต์โมดูล SendKeys บนเซิร์ฟเวอร์ของเราเพื่อให้เราไม่ต้องติดตั้งลงในคอมพิวเตอร์ทุกเครื่อง? ฉันไม่คุ้นเคยกับการเพิ่มโมดูลใหม่
แทนเนอร์

1
คุณสามารถใช้ PYTHONPATH เพื่อเพิ่มลงในไดเรกทอรีเริ่มต้นที่ Python ค้นหาเมื่อนำเข้าโมดูล ฉันไม่เคยใช้สิ่งนี้ดังนั้นฉันจึงไม่สามารถให้คำแนะนำใด ๆ ได้ ข้อมูลเพิ่มเติมที่นี่: docs.python.org/tutorial/modules.html#the-module-search-path
Evan

ขอบคุณ SendKeys ทำงานเมื่อฉันปิด 'มักจะทำงานในเบื้องหน้า' แต่ปัญหาคือเครื่องมือสคริปต์ต้องทำงานในเบื้องหน้าหากคุณใช้ arcpy.mapping.MapDocument ('ปัจจุบัน') ฉันสงสัยว่ามีวิธีที่จะทำหรือไม่ ใน ArcObjects จากนั้นอีกครั้งฉันไม่เคยใช้ ArcObjects
Tanner

1
คุณสามารถเปลี่ยนเครื่องมือให้ทำงานในโหมดโฟร์กราวน์ได้เสมอจากกล่องโต้ตอบคุณสมบัติเครื่องมือสคริปต์
Jason Scheirer

ลิงก์ไปยังโมดูล 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.