अगर ArcMap संपादन सत्र में है, तो आर्कपी के माध्यम से जाँच करना?


11

मैंने एक पायथन ऐड-इन बटन बनाया है जो एक फीचर क्लास की विशेषता को दूसरे में कॉपी करके मेरे सहकर्मियों के वर्कफ़्लो को गति देने में मदद करता है। यह लक्ष्य सुविधा वर्ग में एक पंक्ति को अद्यतन करने के लिए arcpy.UpdateCursor फ़ंक्शन का उपयोग करता है। जैसा कि अभी मौजूद है, यह बटन स्क्रिप्ट संपादन मोड की परवाह किए बिना चलाया जा सकता है। जाहिर है जब एक एडिट सेशन में इसकी रनिंग होती है, तो यूजर एडिटिंग को रोकना और बदलावों को नहीं सहेजना चुन सकता है, लेकिन ऐसा तब नहीं होता है जब स्क्रिप्ट किसी एडिट सेशन के बाहर चलती है।

मैं उस स्क्रिप्ट में एक जांच कैसे जोड़ सकता हूं जो स्क्रिप्ट को चलने से रोक देगी यदि आर्कपाइप वर्तमान में एक संपादन सत्र में नहीं है?

यह आर्कप 10 और 10.1 की चिंता करता है


मैं यह भी सत्यापित करना चाहता हूं कि अन्य आर्कपैम उपयोगकर्ताओं के साथ यह सत्यापित करने के लिए कि तालिकाओं में अपडेट एक संपादन सत्र में होने के बिना सामान्य रूप से अनुमति नहीं है।

तो यह स्क्रिप्ट एक संपादन सत्र के बाहर कैसे चल रही है?

यह स्क्रिप्ट प्रतीत होने वाले गंभीर चयन क्रम के बारे में एक और सवाल भी उठाती है। आर्केपॉर्फ़ यह करता है कि जब मैं किसी सूची से 2 फ़ीचर वर्ग तालिका को अपडेट करता हूँ, तो यह मेरे लिए काम करता है, लेकिन यह एक और दिन के लिए है।

यहाँ स्क्रिप्ट है क्योंकि यह अब काम करता है (बिना किसी 10.1 संपादक कार्यान्वयन के):

उपयोगकर्ता को संपादित सत्र में सुनिश्चित करने के लिए चेक कैसे जोड़ें?

def onClick(self):
    #Reference mxd
    mxd = arcpy.mapping.MapDocument("CURRENT")
    #Reference the main Data frame
    mm = arcpy.mapping.ListDataFrames(mxd, "MainMap")[0]
    #Reference the Water System Valve feature class
    waterValves = arcpy.mapping.ListLayers(mxd, "Water System Valve", mm)[0]
    #Reference the fire hydrant feature class
    fireHydrants = arcpy.mapping.ListLayers(mxd, "Water Hydrant", mm)[0]

    #Use the extent of the main DF to select all valves in the current view
    dfAsFeature = arcpy.Polygon(arcpy.Array([mm.extent.lowerLeft, mm.extent.lowerRight, mm.extent.upperRight, mm.extent.upperLeft]), mm.spatialReference)
    arcpy.SelectLayerByLocation_management(waterValves, "WITHIN", dfAsFeature,"", "NEW_SELECTION")

    arcpy.SelectLayerByAttribute_management(waterValves, "SUBSET_SELECTION", "LOCATIONID IS NULL")

    fields = ["LOCATIONID"]

    row, rows = None, None
    rows = arcpy.UpdateCursor(waterValves,fields)
    row = rows.next()
    valveList = []
    append = valveList.append

    #Loop through the valves table to update LocationID
    while row:
        builder = str(row.QSNO)+"-"+ str(row.VALVESEQNO)
        row.setValue("LOCATIONID", builder)
        append(builder)
        rows.updateRow(row)
        row = rows.next()

    del row, rows

    #New selection for fire hydrants
    arcpy.SelectLayerByLocation_management(fireHydrants, "WITHIN", dfAsFeature,"", "NEW_SELECTION")
    arcpy.SelectLayerByAttribute_management(fireHydrants, "SUBSET_SELECTION", "LOCATIONID IS NULL")

    row, rows = None, None
    rows = arcpy.UpdateCursor(fireHydrants,fields)
    row = rows.next()

    #Loop through fire hydrant table to update LocationID
    while row:
        for locID in valveList:
            construct = str(locID) + "-FH"
            #print construct
            row.setValue("LOCATIONID", construct)
            rows.updateRow(row)
            row = rows.next()

    del row, rows, valveList, mxd

डेटा एक्सेस मॉड्यूल संपादक मानक संपादक से स्वतंत्र संचालित होता है। मैं सक्रिय संपादन सत्र के लिए परीक्षण पर किसी भी अतिरिक्त विचार का स्वागत करूंगा। -Karl
KarlJr

क्या आप थोड़ी और जानकारी प्रदान कर सकते हैं? आपने उन लोगों के लिए इस निष्कर्ष पर क्या पहुंचाया जिन्होंने मॉड्यूल की खोज नहीं की है?
जे लॉरा

जवाबों:


6

यहाँ इस पोस्ट के आधार पर एक सामान्य कार्य है।

हो सकता है कि यह आर्कोबजेक्ट्स सॉल्यूशन की तुलना में थोड़ा अधिक क्यूटिकल हो, लेकिन यह निश्चित रूप से बहुत कम परेशानी की तरह लगता है! सरल जटिल से बेहतर है। सिवाय जब यह नहीं है।

उदाहरण उपयोग:

if CheckEditSession(tbl):
    print("An edit session is currently open.")

कोड:

def CheckEditSession(lyr):
    """Check for an active edit session on an fc or table.
    Return True of edit session active, else False"""
    edit_session = True
    row1 = None
    try:
        # attempt to open two cursors on the input
        # this generates a RuntimeError if no edit session is active
        OID = arcpy.Describe(lyr).OIDFieldName
        with arcpy.da.UpdateCursor(lyr, OID) as rows:
            row = next(rows)
            with arcpy.da.UpdateCursor(lyr, OID) as rows2:
                row2 = next(rows2)
    except RuntimeError as e:
        if e.message == "workspace already in transaction mode":
            # this error means that no edit session is active
            edit_session = False
        else:
            # we have some other error going on, report it
            raise
    return edit_session

+1 अच्छी अवधारणा, हालांकि ओपी एक संपादित सत्र में नहीं होने पर रोकना चाहता है , और यदि यह संपादित सत्र में है तो जारी रखें। आपका उत्तर इसके विपरीत प्रतीत होता है। संभवत: हालांकि इसके आसपास ज्यादा मोड़ नहीं आए।
मिडावेलो

ओपी ने अपनी समस्या पहले से ही हल कर ली है, यह पोस्ट अधिक सामान्यतः उपयोगी फ़ंक्शन के साथ बस आइसिंग है। मैंने अपने उदाहरण को संशोधित किया कि यह कैसे उपयोग किया जाता है।
कर्टिस की कीमत

4

इस समस्या का मेरा समाधान था कि मैं आर्कपी एडिन टूलबार के लिए उपलब्ध एक्सटेंशन का उपयोग करूं। मैंने एक एक्सटेंशन जोड़ा जो संपादन सत्र को शुरू करने या समाप्त करने के लिए सुनता है। मेरे पास बार सेट करने के लिए मेरे सभी बटन हैं: self.enable = False "से शुरू करने के लिए और फिर ये बटन तब एडिट सेशन को शुरू या बंद करके सक्षम या अक्षम होते हैं।

class Active_Edit_Session(object):
"""Implementation for NEZ_EDITS_addin.Listen_for_Edit_Session (Extension)"""
def __init__(self):
    self.enabled = True
def onStartEditing(self):
    button_3100.enabled=True    
def onStopEditing(self, save_changes):
    button_3100.enabled=False

class LFM_3100(object):
    """Implementation for LFM_3100.button_3100 (Button)"""
    def __init__(self):
        self.enabled = False
        self.checked = False
    def onClick(self):
        ......

यह कोशिश करने लायक एक समाधान की तरह दिखता है। धन्यवाद
user18412

4

मैं एक और उत्तर पोस्ट कर रहा हूं क्योंकि मैंने आर्कओबजेक्ट्स और पायथन का एक साथ उपयोग करके आर्कप में संपादक की स्थिति की जांच करने के लिए एक नया तरीका सीखा है। मेरा उत्तर मार्क सेडरहोम द्वारा किए गए काम से बहुत अधिक उधार लेता है जैसा कि इस पोस्ट में उल्लेख किया गया है: मैं पायथन से आर्कोबजेक्ट्स का उपयोग कैसे करूं? , और मैट विल्की ने अपने "स्निपिट्सहोम" फाइल में दिए कोड उदाहरण। आपको कॉमपाइप को डाउनलोड और इंस्टॉल करने के लिए पहले उत्तर में दिए गए निर्देशों का पालन करना होगा और फिर Snippets.py स्क्रिप्ट की एक प्रति प्राप्त करनी होगी। मैं नीचे उस लिपि से आवश्यक कार्यों की एक प्रति पोस्ट कर रहा हूं।

जब फ़ंक्शन ArcMap_GetEditSessionStatus () कहा जाता है, तो यह ArcMap में संपादक की वर्तमान स्थिति की जांच करेगा और सही या गलत लौटेगा। यह मुझे जांचने देता है कि क्या कोई उपयोगकर्ता मेरे टूल का उपयोग करने के लिए तैयार है या यदि उन्हें एक संपादित सत्र शुरू करने के लिए प्रेरित करने की आवश्यकता है। इस विधि में नकारात्मक पक्ष यह है कि पाइथन में आर्कोबजेक्ट्स का उपयोग करने से पहले कॉम्पटियों को स्थापित करने की आवश्यकता होती है, इसलिए एक उपकरण को साझा करना जिसके लिए एक बहु-उपयोगकर्ता कार्यालय वातावरण में इस पैकेज की आवश्यकता हो सकती है। अपने सीमित अनुभव के साथ मुझे यकीन नहीं है कि एश्री पायथन टूल ऐड-इन के रूप में आसान साझा करने के लिए यह सब कैसे एक साथ बांधना है। ऐसा करने के लिए सुझाव की सराहना की जाएगी।

#From the Snippits.py file created by Matt Wilkie
def NewObj(MyClass, MyInterface):
    """Creates a new comtypes POINTER object where\n\
    MyClass is the class to be instantiated,\n\
    MyInterface is the interface to be assigned"""
    from comtypes.client import CreateObject
    try:
        ptr = CreateObject(MyClass, interface=MyInterface)
        return ptr
    except:
        return None

def CType(obj, interface):
    """Casts obj to interface and returns comtypes POINTER or None"""
    try:
        newobj = obj.QueryInterface(interface)
        return newobj
    except:
        return None

def CLSID(MyClass):
    """Return CLSID of MyClass as string"""
    return str(MyClass._reg_clsid_)

def GetApp(app="ArcMap"):
    """app must be 'ArcMap' (default) or 'ArcCatalog'\n\
    Execute GetDesktopModules() first"""
    if not (app == "ArcMap" or app == "ArcCatalog"):
        print "app must be 'ArcMap' or 'ArcCatalog'"
        return None
    import comtypes.gen.esriFramework as esriFramework
    import comtypes.gen.esriArcMapUI as esriArcMapUI
    import comtypes.gen.esriCatalogUI as esriCatalogUI
    pAppROT = NewObj(esriFramework.AppROT, esriFramework.IAppROT)
    iCount = pAppROT.Count
    if iCount == 0:
        return None
    for i in range(iCount):
        pApp = pAppROT.Item(i)
        if app == "ArcCatalog":
            if CType(pApp, esriCatalogUI.IGxApplication):
                return pApp
            continue
        if CType(pApp, esriArcMapUI.IMxApplication):
            return pApp
    return None


def GetModule(sModuleName):
    """Import ArcGIS module"""
    from comtypes.client import GetModule
    sLibPath = GetLibPath()
    GetModule(sLibPath + sModuleName)


def GetDesktopModules():
    """Import basic ArcGIS Desktop libraries"""
    GetModule("esriFramework.olb")
    GetModule("esriArcMapUI.olb")

#My added function for checking edit session status
def ArcMap_GetEditSessionStatus():

    GetDesktopModules()
    GetModule("esriEditor.olb")
    import comtypes.gen.esriSystem as esriSystem
    import comtypes.gen.esriEditor as esriEditor
    pApp = GetApp()
    pID = NewObj(esriSystem.UID, esriSystem.IUID)
    pID.Value = CLSID(esriEditor.Editor)
    pExt = pApp.FindExtensionByCLSID(pID)
    pEditor = CType(pExt, esriEditor.IEditor)
    if pEditor.EditState == esriEditor.esriStateEditing:
        print "Edit session active"
        return True
    else:
        print "Not in an edit session"
        return False

1
यह बहुत अच्छा काम करता है। मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन यदि आप इसे पैकेज करना चाहते हैं तो यह अधिक पोर्टेबल है, आप स्निपेट्स मॉड्यूल को अजगर पैकेज के रूप में बना सकते हैं , और इसके भीतर कॉमपाइप्स शामिल कर सकते हैं। मैं अपनी कंपनी के लिए ऐसा करता हूं और मैंने अपने सभी कस्टम पायथन मॉड्यूल को नेटवर्क शेयर पर रखा है। हर बार जब कोई आर्कगिस सॉफ़्टवेयर को स्थापित / फिर से इंस्टॉल करता है, तो मैंने उन्हें एक बैच फ़ाइल चलाने के Desktop.pthलिए कहा है जो नेटवर्क फ़ाइल में पूर्ण पथ को शामिल करने के लिए उनकी फ़ाइल को संशोधित करता है , इसलिए हर कोई स्वचालित रूप से सब कुछ आयात कर सकता है।
crmackey

2

डेटा एक्सेस मॉड्यूल का उपयोग कैसे करें ? ऐसा लगता है कि आप इस मॉड्यूल के साथ एक संपादन सत्र शुरू कर सकते हैं।

कुछ चेतावनी:

  1. मैंने इस मॉड्यूल की कोशिश नहीं की है और यह सुनिश्चित नहीं है कि यह 10.0 संगत है। (10.1 में नया?)
  2. उदाहरण 1 एक withबयान के उपयोग को दर्शाता है । यह लागू करने के लिए एक महान प्रतिमान है क्योंकि यह संभावित अपवादों को अच्छी तरह से संभालता है।
  3. यदि आप एक try / exceptबयान में एक को लॉन्च करने का प्रयास करके एक संपादित सत्र पहले से ही रहते हैं, तो आप परीक्षण करने में सक्षम हो सकते हैं ।

मैंने वास्तव में डेटा एक्सेस मॉड्यूल में संपादक वर्ग का उपयोग करने के साथ शुरू किया था जब मैंने इस परियोजना को शुरू किया था लेकिन इसका उपयोग करने से कोई फर्क नहीं पड़ता था। मेरी स्क्रिप्ट में "arcpy.da.Editor (कार्यक्षेत्र) के साथ संपादन सहित:" मेरी स्क्रिप्ट में संपादक को सक्रिय नहीं किया गया था, और स्टॉपऑपरेशन / स्टॉप की कोशिश कर रहा था। एडिटिंग ने संपादक को नहीं रोका। लेकिन मैं इसे गलत कर सकता था ...
user18412

1

तो यह है कि मैं कैसे मेरे उपकरण का उपयोग कर रहा है अगर एक संपादन सत्र में था या नहीं करने के लिए सक्षम नहीं होने के अपने मुद्दे को तय किया है:

#Reference to mxd and layers script here. Then...
try:
    fields = ("OBJECTID")
    upCursor = arcpy.da.UpdateCursor(waterValves, fields)
    with upCursor as cursor:
        for row in cursor:
            pass
except:
    pythonaddins.MessageBox('You are not in an edit session', 'Warning', 0)

else:
#Rest of script

स्क्रिप्ट काम करती है क्योंकि यह एक लेयर पर एक UpdateCursor बनाने की कोशिश करती है जिसमें बाद में एक और UpdateCursor होता है। यह डेटा एक्सेस मॉड्यूल के व्यवहार का उल्लंघन करता है। ESRI संसाधन पृष्ठ के अनुसार arcpy.da.UpdateCursor पर:

"अलग-अलग कर्सर का उपयोग करके एक ही कार्यक्षेत्र पर एक साथ सम्मिलित और / या अपडेट ऑपरेशन खोलने के लिए एक संपादन सत्र की शुरुआत की आवश्यकता होती है।"

मैं इस समाधान से खुश नहीं हूं क्योंकि यह एक हैक से अधिक है जो मैं कल्पना करता हूं कि उचित चापलूसी स्क्रिप्टिंग है। किसी को भी बेहतर विचार?


1
यह सिर्फ एक विचार है, लेकिन आप ArcObjects में संपादक ऑब्जेक्ट तक पहुंचने की कोशिश कर सकते हैं और इसकी संपत्ति की जांच कर सकते हैं EditState जो लगता है कि आर्कपी से गायब है? मैंने पायथन से आर्कोबजेक्ट्स में हेरफेर करने की कभी कोशिश नहीं की है, लेकिन यह धागा कैसे करना है इसके बारे में बात करता है?
हॉर्नबड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.