पायथन से ArcObjects तक पहुँच?


132

मैं कुछ ऐसी चीजों को स्क्रिप्ट करने में सक्षम होना चाहूंगा जो कि arcgisscriptingया आर्कपी के माध्यम से उजागर नहीं होती हैं।

मैं पायथन से ArcObjects का उपयोग कैसे करूं ?


3
किसी को भी उत्पादन वातावरण में इन तरीकों का उपयोग करने पर विचार है? यूसी में कुछ साल पहले मैंने ESRI C ++ के एक देवता के साथ बात की थी जो अपने अधिकांश पायथन मॉड्यूल लिखते हैं और वह एक उत्पादन वातावरण में आयरनपाइथन का उपयोग करने के सख्त खिलाफ थे - लेकिन वह कुछ साल पहले था।
चाड कूपर

जवाबों:


113

Comtypes * को डाउनलोड और इंस्टॉल करें , SnippetsPYTHONPATH में मार्क सेडरहोम से मॉड्यूल डालें, और आप सभी सेट हैं।

from snippets102 import GetLibPath, InitStandalone
from comtypes.client import GetModule, CreateObject
m = GetModule(GetLibPath() + "esriGeometry.olb")
InitStandalone()
p = CreateObject(m.Point, interface=m.IPoint)
p.PutCoords(2,3)
print p.X, p.Y

बैकग्राउंड के लिए UberPyGeeks के लिए मार्क सीडरहोम की प्रस्तुतियों को "पायथन में आर्कओब्जेक्ट्स का उपयोग करना" देखें । वीबीए और सी ++ डेवलपर दृष्टिकोण के लिए अलग-अलग हैं। वे विजुअल स्टूडियो (हाँ एक्सप्रेस ठीक है) और विंडोज एसडीके का उपयोग करते हैं , लेकिन इनकी आवश्यकता नहीं है, बस आर्कगिस, पायथन और कॉम्पटिप पर्याप्त हैं।

स्निपेट्स मॉड्यूल प्राप्त करना

* 10.1+ के लिए ध्यान दें आपको automation.pyकॉम्पटिप मॉड्यूल में एक छोटा सा बदलाव करने की आवश्यकता है। 10.1 पर ArcObjects + comtypes देखें ।


अगला कदम

... या: दिमाग सनक गया ? सी # कोड उदाहरणों को देखते हुए आपकी आँखें तैर जाती हैं, और कोशिश करें कि आप एक क्रेन की तरह नहीं सोच सकते ? इधर देखो:


10
इस धागे को मेरे ध्यान में लाया गया है, और ऐसा लगता है कि कुछ गलत धारणाएं हैं जो चारों ओर तैर रही हैं। पायथन में आर्कोबजेक्ट्स का उपयोग करने के लिए आपको विजुअल स्टूडियो या एमआईडीएल कंपाइलर की आवश्यकता नहीं है; आप सभी की जरूरत है comtypes पैकेज है। मेरी प्रस्तुति में पायथन का उपयोग करके COM घटक बनाने के लिए एक उन्नत अभ्यास शामिल था, लेकिन यह UberPyGeeks के लिए था। Snippets.py फ़ाइल में आपके लिए आवश्यक सभी उदाहरण हैं।

1
@ मर्क, सुधार के लिए बहुत धन्यवाद। स्पष्ट होने के लिए: उपरोक्त नुस्खा में 1,3,4 कदमों को हटा सकता है जब तक कि ctypes पहले से ही स्थापित नहीं है?
मैट विल्की

2
हाँ। लैब में इसका परीक्षण किया। आपको बस कॉम्पटिस को स्थापित करने की आवश्यकता है।
RK

@ आरके, महान! सत्यापन के लिए धन्यवाद और उत्तर को आज तक लाया गया।
मैट विल्की

1
स्निपेट्स मॉड्यूल यहां पर इंस्टॉल किए गए एओ मॉड्यूल के रूप में फिर से आता है: github.com/maphew/arcplus/tree/master/arcplus/ao (10.3 के लिए अद्यतन, 10.2 के लिए फ़ाइल के पिछले संस्करण देखें)। एक बार जब मैं कुछ बग्स को साफ कर दूंगा तो मुख्य उत्तर को अपडेट कर दूंगा।
मैट विल्की

32

हां, मार्क सीडरहोम की प्रस्तुति जो मैट विल्की का उल्लेख करती है, शुरू करने के लिए एक शानदार जगह है। मैट द्वारा प्रस्तुत नुस्खा / कोड निश्चित रूप से एक चालाक है और शायद चीजों के बारे में जाने का सबसे अच्छा तरीका है। मैं जिक्र करना चाहता था, हालाँकि, मैं बलगम विधि का उपयोग कर रहा हूँ जिसका उपयोग मैं आर्कगिस 10.0 में कर रहा हूँ। मेरे पास कई स्वचालन स्क्रिप्ट हैं (स्टैंडअलोन, एप्लिकेशन सीमा के बाहर) जो मैं इस तरह से चलाता हूं, और वे बस ठीक काम करते हैं। यदि अधिकतम गति एक चिंता का विषय है, हालांकि, आप सिर्फ मैट के समाधान के साथ जा सकते हैं और इसके साथ किया जा सकता है।

मैं सभी ArcObjects पुस्तकालयों (.olb) के रैपिंग को मजबूर करने के लिए comtypes पैकेज का उपयोग करता हूं। फिर पायथन की सभी आर्कोबजेक्ट्स तक पहुंच है। मुझे ईएसआरआई फोरम पोस्टिंग के माध्यम से फ्रैंक पर्क से रैपिंग कोड मिला । मेरा अपना कोड था जो अनिवार्य रूप से एक ही काम करता था, लेकिन यह फूला हुआ था और केवल कार्यात्मक था, जबकि उसका बहुत सुंदर है। इसलिए:

import sys, os
if '[path to your Python script/module directory]' not in sys.path:
    sys.path.append('[path to your Python script/module directory]')

import comtypes
#force wrapping of all ArcObjects libraries (OLBs)
import comtypes.client
# change com_dir to whatever it is for you
com_dir = r'C:\Program Files (x86)\ArcGIS\Desktop10.0\com'
coms = [os.path.join(com_dir, x) for x in os.listdir(com_dir) if os.path.splitext(x)[1].upper() == '.OLB']
map(comtypes.client.GetModule, coms)

फिर, मार्क सेडरहोम की प्रस्तुति से बहुत सीधे बाहर:

import comtypes.gen.esriFramework

pApp = GetApp()

def GetApp():
    """Get a hook into the current session of ArcMap"""
    pAppROT = NewObj(esriFramework.AppROT, esriFramework.IAppROT)
    iCount = pAppROT.Count

    if iCount == 0:
        print 'No ArcGIS application currently running.  Terminating ...'
        return None
    for i in range(iCount):
        pApp = pAppROT.Item(i)  #returns IApplication on AppRef
        if pApp.Name == 'ArcMap':
            return pApp
    print 'No ArcMap session is running at this time.'
    return None

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

बस। आपके पास आर्कऑब्जेक्ट्स के लिए पूर्ण पहुंच होनी चाहिए जो कि PAP ऑब्जेक्ट के साथ शुरू होता है जो कि AppRef ऑब्जेक्ट पर IApplication है। मेरे अनुभव में, पहले रन पर आर्कोबजेक्ट्स लाइब्रेरी की रैपिंग आपत्तिजनक रूप से धीमी नहीं है, और बाद के रनिंग के लिए रैपिंग नहीं होती है। पुस्तकालय पहले से ही लिपटे और संकलित हैं, इसलिए चीजें बहुत तेज हैं।

जोड़ा: इसके साथ आने वाली एक बड़ी सावधानी है। यहां दिए गए NewObj फ़ंक्शन ने माना कि पायथन लिपि को प्रक्रिया में चलाया जा रहा है। यदि नहीं, तो यह फ़ंक्शन पायथन प्रक्रिया में ऑब्जेक्ट्स बनाएगा (अर्थात प्रक्रिया से बाहर), और ऑब्जेक्ट संदर्भ गलत होंगे। बाहरी पायथन स्क्रिप्ट से प्रक्रिया ऑब्जेक्ट बनाने के लिए आपको IObjectFactory का उपयोग करना चाहिए। अधिक जानकारी के लिए इस स्टैकएक्सचेंज पोस्ट में कर्क कुक्केंडल की टिप्पणियों और सुझावों को देखें ।


1
इस दृष्टिकोण के बारे में अच्छी बात यह है कि इसे विजुअल स्टूडियो को स्थापित करने की आवश्यकता नहीं है, जो कि बहुत भारी है अगर केवल एक चीज जो आप कभी भी इसके साथ करेंगे वह कॉम वस्तुओं को पंजीकृत करना है। अगर मैं इस शुद्ध अजगर विधि के बारे में जानता हूँ तो मैंने कभी भी Cederholm मार्ग की कोशिश नहीं की होगी। ;-)
मैट विल्की

1
मैंने इस उत्तर में इस अवधारणा पर थोड़ा विस्तार किया, आयात करना और टाइप लाइब्रेरीज़ को एक-चरणीय प्रक्रिया में लपेटना
blah238

20

मैं अजगर से आर्कोबिज कैसे पहुंचता हूं?

यदि आप जिस चीज़ की तलाश कर रहे हैं, वह विशिष्ट कार्यक्षमता है जो मौजूद है और सी ++ आर्कबॉजेक्ट्स कोड में है, तो आपका सबसे अच्छा शर्त यह होगा कि आप उन्हें कॉल करने के लिए सी ++ तरीके बनाएं .... और फिर उन सी ++ विधियों का उपयोग करने के लिए एक अजगर आवरण बनाएँ।

अजगर से C ++ विधियों का उपयोग करने के लिए काफी कुछ तरीके हैं, और बहुत से लोग जो ऐसा करते हैं, जो कि C ++ विधि हस्ताक्षर से अजगर कक्षाओं को ऑटो-जनरेट करने के लिए SWIG जैसे उपकरण का उपयोग करते हैं । यह मेरा अनुभव रहा है कि इन ऑटोजेनरेटेड एपीआई को गैर-देशी सी ++ प्रकार (इंट, फ्लोट्स) पास करते समय बहुत बुरा लगता है और कभी भी बहुत ' पाइथोनिक ' नहीं होते हैं ।

मेरा अनुशंसित समाधान ctypes API का उपयोग करना होगा। एक महान ट्यूटोरियल यहाँ है: http://python.net/crew/theller/ctypes/tutorial.html

बुनियादी कदम हैं:

  1. अपने कुछ मुख्य तर्क C ++ में लिखें, जहाँ आप मानते हैं कि अजगर का प्रदर्शन एक मुद्दा हो सकता है
  2. एक साझा (.so) या डायनेमिक लाइब्रेरी (.dll) में जो भी सिस्टम कंपाइलर (nmake, मेक, इत्यादि) का उपयोग कर ऑब्जेक्ट फ़ाइलों से कोर लॉजिक (इस मामले में ArcObject C ++ API विधि कॉल का उपयोग करके) संकलित करें।
  3. अजगर वर्ग और C ++ विधि हस्ताक्षर के बीच एक ctypes मैपिंग लिखें [SWIG इसे स्वचालित करने की कोशिश करता है, लेकिन यह आसान है, भले ही पागल वस्तु प्रकारों का उपयोग कर]
  4. संकलित पुस्तकालय को अपने अजगर कार्यक्रम में आयात करें और किसी भी अन्य अजगर वर्ग की तरह बाध्य वर्ग / विधि बाइंडिंग का उपयोग करें!

यह शायद अजगर के भीतर से C / C ++ कोड को संदर्भित करने के लिए अधिक सामान्य तरीका है, यह संभवत: लंबे समय में बहुत सरल होने जा रहा है यदि आपको COM ऑब्जेक्ट से निपटना नहीं है। यह सभी सिस्टम विशिष्ट कार्यक्षमता को लिंक किए गए लाइब्रेरी ऑब्जेक्ट के संकलन में भी रहने देगा (ताकि अजगर सिस्टम / पायथन कार्यान्वयन विशिष्ट नहीं होगा)।


3
यह आर्कओबजेक्ट्स के साथ बातचीत करने का सबसे अच्छा तरीका है। कॉमपाइप का उपयोग प्रोटोटाइप के लिए बहुत अच्छा है लेकिन अपने स्वयं के सी एक्सटेंशन को लिखने से एक अच्छा, पायथनिक डिजाइन (क्योंकि आपको इसके बारे में सोचना होगा) और बेहतर प्रदर्शन होगा क्योंकि आप सी ++ / पायथन ऑब्जेक्ट बाधा को पार नहीं करते हैं। हालांकि व्यावहारिक उद्देश्यों के लिए, यह डिजाइन / विकसित / डिबग करना कठिन है, इसलिए त्वरित और गंदा खिड़की से बाहर चला जाता है।
जेसन शहीर

18

एक और विकल्प .NET के लिए पायथन का उपयोग करना है - यह सेट करना बहुत आसान है, और आर्कओबजेक्ट सहित किसी भी .NET DLL के साथ काम कर सकते हैं।

मैंने इन-प्रोसेस ओब्सेस के साथ किसी भी समस्या का अनुभव नहीं किया है, और आर्कपेज़ का एक उदाहरण खोलना और परतों को जोड़ना और हेरफेर करना मेरे लिए ठीक काम किया है।

केवल आवश्यकताएँ .NET लाइब्रेरी के लिए पायथन से युक्त एक फ़ोल्डर हैं, और एक मानक पायथन स्थापित है।

अधिक विवरण और नमूना लिपि यहाँ । नमूना लिपि को सीधे http://gist.github.com/923954 पर भी देखा जा सकता है

दुर्भाग्य से, जब यह एक स्थानीय विकास मशीन पर समस्याओं के बिना काम करता है, तो इसे कहीं और तैनात करने के लिए ArcObjects SDK, और Visual Studio (मुक्त एक्सप्रेस संस्करण सहित) की आवश्यकता होती है। तैनात करना देखें


नुस्खा स्पष्ट, स्पष्ट और अच्छी तरह से प्रस्तुत किया गया है। धन्यवाद जियोग्राफिका! मैं आपको अपने उत्तर में एक न्यूनतम स्क्रिप्ट स्निपेट शामिल करने के लिए प्रोत्साहित करता हूं, ताकि घटना में आपकी साइट का नवीनीकरण हो जाए और उत्तर स्वयं पर खड़ा हो सके।
मैट विल्की

1
ठीक ऐसा ही मैंने इस पुराने ब्लॉगपोस्ट ( gissolved.blogspot.com/2009/06/python-toolbox-3-pythonnet.html ) में किया और यह उम्मीद के मुताबिक काम करता है लेकिन ऐसे नतीजे ज़रूर दें जो आपके पायथन को समझे (स्ट्रिंग्स, नंबर) या शून्य)।
शमूएल

लिंक geographika.co.uk/use-arcobjects-and-net-in-python टूट गया है।
SIslam

5

अन्य दृष्टिकोणों में उल्लिखित एक दृष्टिकोण मुझे उन्हीं विधियों का उपयोग करने के लिए है, जो स्वयं आर्कपी लाइब्रेरीज़ उपयोग करते हैं। उदाहरण के लिए C: \ Program Files \ ArcGIS \ Desktop10.0 \ arcpy \ arcpy \ cartography.py, हम पायथन को कुछ फिक्सार्ग और ऑब्जेक्ट रूपांतरण कार्यों का उपयोग करते हुए आर्केओबजेक्ट्स टूल बुलाते हुए देखते हैं।

मैं इसके बारे में यहां पोस्ट करने के लिए कितना ठीक हूं, क्योंकि कोड "ट्रेड सिक्रेट: ESRI PROPRIETARY AND CONFIDENTIAL" कहता है; लेकिन आप इसे वेब पर भी कहीं और पाएंगे। वैसे भी, यह SimplifyBuilding_cartography()कॉम्पटियों या किसी अन्य अतिरिक्त पुस्तकालयों को स्थापित किए बिना कार्यों को कॉल करने के लिए अपेक्षाकृत आसान तरीका लगता है ।

संपादित करें:

नीचे जेसन की टिप्पणियाँ देखें। ऐसा लगता है कि ऊपर करने से आप बहुत कुछ नहीं खरीदेंगे।


मैंने उस पर भी ध्यान दिया, हालांकि बहुत ज्यादा वूडू जैसा लगता है।
ब्लाह 238

1
यह आर्कोबिज के पूरी तरह से उजागर सेट को नहीं बुला रहा है।
जेसन शहीर

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

1
मैं आपको एक तथ्य के लिए आश्वस्त कर सकता हूं जो यह नहीं करता है। मैंने इसका बहुत विकास किया।
जेसन शेखर

1
आप नहीं कर सकते। "आर्कोबजेक्ट" इस उदाहरण में एक मिथ्या नाम का एक सा है। अंतर्निहित वस्तुओं को प्राप्त करने का कोई तरीका नहीं है, और आर्कगिसस्क्रिप्टिंग / आर्कपी में कहीं भी सभी आर्कबोज को उजागर करने वाला कोई COM बाइंडिंग नहीं है।
जेसन शहीर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.