पायथन से आर्कोबजेक्ट्स का उपयोग करने के लिए दिशानिर्देश


10

अब तक, पायथन से आर्कओबजेक्ट्स एक्सेस करना? जीआईएस स्टैक एक्सचेंज में मेरा सबसे अधिक पढ़ा गया और संदर्भित प्रश्नोत्तर है। उस सफलता के बावजूद, यह संभवतः मेरे सबसे कमजोर क्षेत्रों में से एक है जब वास्तविक उपयोग की बात आती है। उस गरीब को दिखाने का एक बड़ा हिस्सा आर्कबोजेक्ट डॉक्स को पढ़ने और समझने की मेरी खराब क्षमता से निकला है ।

तो, किसी भी दिए गए कार्य के लिए .net / c ++ / java / ... डॉक्स और उदाहरणों को अपने अजगर समकक्षों में अनुवाद करने के लिए कुछ दिशानिर्देश क्या हैं? (उस मामले के लिए किस भाषा से काम करना सबसे अच्छा है?) और शुरुआत करने के लिए सबसे अच्छा सूचकांक या लैंडिंग पृष्ठ क्या है? क्या सामान पर ध्यान केंद्रित किया जाना चाहिए, और कम से कम महत्वपूर्ण रूप से महत्वपूर्ण है, क्या स्वतंत्र रूप से अनदेखा किया जा सकता है?

अपने दर्शकों को मान लें कि कम से कम कुछ अजगर साक्षर हैं, और अन्य विकास भाषाओं में अनपढ़ हैं। प्रारंभिक विचार और अनुसंधान से लेकर काम करने वाले अजगर परिणामों तक, एक छोटे कोडिंग अभ्यास के माध्यम से हमें चलें।


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

उपयोग करने के लिए एक संभावित उदाहरण: gis.stackexchange.com/questions/86007/… (प्रकटीकरण: यह वह समस्या है जिस पर मैं काम कर रहा हूं, जिसने Q को हराया। ; ;-)
मैट विल्की

आर्कोबजेक्ट्स को प्राप्त करना मुश्किल हो सकता है, मदद डॉक्स ठीक है लेकिन उदाहरण बेहतर हैं: सबसे बड़ी समस्याओं में से एक वस्तु का दूसरे से विरासत में बाहर काम कर रहा है, जैसे मुझे ऑब्जेक्ट एक्स मिला है, अब मुझे ऑब्जेक्ट वाई कैसे मिलेगा ? यदि आप विजुअल स्टूडियो 2008 या 2010 एक्सप्रेस (यदि आप इसे पा सकते हैं तो मुफ्त डाउनलोड करें) पर अपने हाथ पा सकते हैं तो एसडीके स्थापित करें आपको स्थानीय स्तर पर सहायता डॉक्स और उदाहरणों का एक गुच्छा मिलेगा।
माइकल स्टिम्सन

1
@mattwilkie को उम्मीद है कि इससे पानी बहुत ज्यादा नहीं बहेगा ... लेकिन मौजूदा .NET कोड को अजगर तक पहुंचाने के लिए और टाइप कास्टिंग सिंटैक्स को पता लगाने के लिए, .NET के लिए अजगर कॉमरेड्स के दृष्टिकोण की तुलना में थोड़ा और आगे दिखता है । उस ने कहा, मैंने केवल .NET के लिए अजगर की खोज की है और अभी तक इसका परीक्षण नहीं किया है।
user2856

1
@mattwilkie ने अभी-अभी python.Net की खोज की है, ArcGIS डेस्कटॉप के अलावा ArcGIS SDK को स्थापित करने की आवश्यकता है (जब तक कि असेंबली रैपर dll को स्क्रिप्ट के साथ वितरित नहीं किया जाता ...), इसलिए कॉम्पीटीज़ दृष्टिकोण के रूप में काफी पोर्टेबल नहीं है।
user2856

जवाबों:


9

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

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

from snippets import *
def add_line(pApp=None, name='Line', x=None, y=None, end_x=None, end_y=None,
             x_len=0, y_len=0, anchor=0, view='layout'):
    '''adds a line to an ArcMap Document

    Required:
    pApp -- reference to either open ArcMap document or path on disk
    name -- name of line element

    Optional:
    x -- start x coordinate, if none, middle of the extent will be used (data view)
    y -- start y coordinate, if none, middle of the extent will be used (data view)
    end_x -- end x coordinate, if making straight lines use x_len
    end_y -- end y coordinate, if making straight lines use y_len
    x_len -- length of line in east/west direction
    y_len -- length of line in north/south direction
    anchor -- anchor point for line element
    view -- choose view for text element (layout|data)

        Anchor Points:
        esriTopLeftCorner   0   Anchor to the top left corner.
        esriTopMidPoint     1   Anchor to the top mid point.
        esriTopRightCorner  2   Anchor to the top right corner.
        esriLeftMidPoint    3   Anchor to the left mid point.
        esriCenterPoint     4   Anchor to the center point.
        esriRightMidPoint   5   Anchor to the right mid point.
        esriBottomLeftCorner    6   Anchor to the bottom left corner.
        esriBottomMidPoint  7   Anchor to the bottom mid point.
        esriBottomRightCorner   8   Anchor to the botton right corner.
    '''
    GetDesktopModules()
    import comtypes.gen.esriFramework as esriFramework
    import comtypes.gen.esriArcMapUI as esriArcMapUI
    import comtypes.gen.esriSystem as esriSystem
    import comtypes.gen.esriGeometry as esriGeometry
    import comtypes.gen.esriCarto as esriCarto
    import comtypes.gen.esriDisplay as esriDisplay
    import comtypes.gen.stdole as stdole

    # set mxd
    if not pApp:
        pApp = GetApp()
    pDoc = pApp.Document
    pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)
    pMap = pMxDoc.FocusMap
    pMapL = pMap
    if view.lower() == 'layout':
        pMapL = pMxDoc.PageLayout
    pAV = CType(pMapL, esriCarto.IActiveView)
    pSD = pAV.ScreenDisplay

    # set coords for elment
    pFact = CType(pApp, esriFramework.IObjectFactory)
    if view.lower() == 'data':
        pEnv = pAV.Extent
        if x == None:
            x = (pEnv.XMin + pEnv.XMax) / 2
        if y == None:
            y = (pEnv.YMin + pEnv.YMax) / 2
    else:
        # default layout position, move off page
        if x == None: x = -4
        if y == None: y = 4

    # from point
    pUnk_pt = pFact.Create(CLSID(esriGeometry.Point))
    pPt = CType(pUnk_pt, esriGeometry.IPoint)
    pPt.PutCoords(x, y)

    # to point
    pUnk_pt2 = pFact.Create(CLSID(esriGeometry.Point))
    pPt2 = CType(pUnk_pt2, esriGeometry.IPoint)
    if x_len or y_len:
        pPt2.PutCoords(x + x_len, y + y_len)
    elif end_x or end_y:
        pPt2.PutCoords(end_x, end_y)

    # line (from point - to point)
    pUnk_line = pFact.Create(CLSID(esriGeometry.Polyline))
    pLg = CType(pUnk_line, esriGeometry.IPolyline)
    pLg.FromPoint = pPt
    pLg.ToPoint = pPt2

    # preset color according to RGB values
    pUnk_color = pFact.Create(CLSID(esriDisplay.RgbColor))
    pColor = CType(pUnk_color, esriDisplay.IRgbColor)
    pColor.Red, pColor.Green, pColor.Blue = (0,0,0) #black line

    # set line properties
    pUnk_line = pFact.Create(CLSID(esriDisplay.SimpleLineSymbol))
    pLineSymbol = CType(pUnk_line, esriDisplay.ISimpleLineSymbol)
    pLineSymbol.Color = pColor

    # create the actual element
    pUnk_elm = pFact.Create(CLSID(esriCarto.LineElement))
    pLineElement = CType(pUnk_elm, esriCarto.ILineElement)
    pLineElement.Symbol = pLineSymbol
    pElement = CType(pLineElement, esriCarto.IElement)

    # elm properties
    pElmProp = CType(pElement, esriCarto.IElementProperties3)
    pElmProp.Name = name
    pElmProp.AnchorPoint = esriCarto.esriAnchorPointEnum(anchor)
    pElement.Geometry = pLg

    # add to map
    pGC = CType(pMapL, esriCarto.IGraphicsContainer)
    pGC.AddElement(pElement, 0)
    pGCSel = CType(pMapL, esriCarto.IGraphicsContainerSelect)
    pGCSel.SelectElement(pElement)
    iOpt = esriCarto.esriViewGraphics + \
    esriCarto.esriViewGraphicSelection
    pAV.PartialRefresh(iOpt, None, None)
    return pElement

if __name__ == '__main__':

    # testing (make a triangle)
    add_line(name='hypot', end_x=-2, end_y=2, anchor=3)
    add_line(name='vertLine', y_len=-2, anchor=1)
    add_line(name='bottom', y=2, end_x=-2, end_y=2)

यहां छवि विवरण दर्ज करें

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

@ मट्ट विल्की

आयातों का पता लगाने के लिए, जहाँ आपको आर्कओबजेक्ट्स मॉडल आरेखों को देखना होगा या यह देखना होगा कि .NET SDK हेल्प डॉक्स में किसी विशेष वर्ग या इंटरफ़ेस से किस नामस्थान को बुलाया जा रहा है। कुछ मामलों में विरासत के कारण एक से अधिक नाम स्थान का उपयोग किया जा सकता है।

मैं ArcObjects में कोई विशेषज्ञ नहीं हूं, इसलिए आमतौर पर मुझे यह पता लगाने में थोड़ा समय लगता है कि सीटीपे () के साथ चीजों को कब डालना है। इस सबसे, मैंने नमूनों को ऑनलाइन उठाया है। इसके अलावा, VB.NET उदाहरणों से वाक्यविन्यास आप पायथन में क्या करते हैं, के करीब लगता है, लेकिन C # उदाहरण मेरे लिए पठनीयता के संदर्भ में अधिक समझ में आता है (यदि इसका कोई मतलब है)। लेकिन, अंगूठे के एक नियम के रूप में, मैं आमतौर पर इन चरणों को पूरा करता हूं:

  1. किसी नए COM ऑब्जेक्ट (आमतौर पर एक वर्ग) के लिए एक चर बनाने के लिए एक वस्तु तात्कालिक
  2. विधियों और भविष्यवाणियों तक पहुंच की अनुमति देने के लिए COM ऑब्जेक्ट को एक इंटरफ़ेस (ओं) में डालने के लिए CType का उपयोग करें। CType, QueryInterface () के माध्यम से comtypes Interface Pointer को भी लौटाएगा। एक बार पॉइंटर वापस आने के बाद, आप इसके गुणों और विधियों के साथ बातचीत कर सकते हैं।

सुनिश्चित नहीं है कि मैं उचित शब्दावली का उपयोग कर रहा हूं या नहीं ... मैं मुख्य रूप से एक पायथन डेवलपर हूं जो कुछ आर्कोबजेक्ट्स में "डबल्स" करता है ... मैंने केवल हिमशैल के सिरे को छुआ है हालांकि।

साथ ही, यह हेल्पर फंक्शन सभी आर्कबजेक्ट्स ऑब्जेक्ट लाइब्रेरीज़ (.olb) को लोड करेगा।

def load_all():
    '''loads all object libraries'''
    from comtypes.client import GetModule
    mods = glob.glob(os.path.join(GetLibPath(), '*.olb'))
    for mod in mods:
        GetModule(mod)
    return


def GetLibPath():
    '''Reference to com directory which houses ArcObjects
    Ojbect Libraries (*.OLB)'''
    return glob.glob(os.path.join(arcpy.GetInstallInfo()['InstallDir'], 'com'))[0]

उपयोगी उदाहरण के लिए धन्यवाद! क्यू का जोर विशिष्ट कार्य व्यंजनों पर कम (और होने का) है और सबसे पहले कैसे एक जगह पर नुस्खा बनाने के लिए जानकारी मिलती है और कैसे लिखी जाती है। उदाहरण के लिए, आपको कैसे पता चला import comtypes.gen.esriArcMapUI as esriArcMapUIऔर फिर बाद में pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)(उस कथन में वाक्यविन्यास को उजागर करने के लिए) का उपयोग किया?
मैट विल्की

मैंने आपके प्रश्नों का उत्तर देने के लिए अपना मूल उत्तर संपादित किया। मेरे पास कुछ अन्य उदाहरण भी हैं, लेकिन उपरोक्त स्निपेट शायद सबसे अधिक पठनीय है।
crmackey

इसके अलावा, मैंने यह किताब पिछले साल खरीदी थी: amazon.com/Beginning-ArcGIS-Desktop-Development-using/dp/…
crmackey

7

में एक और, संबंधित लेकिन थोड़ा अलग, पोस्ट मैं एक जवाब है कि ESRI ArcObjects मदद डॉक्स के आसपास उनके सिर लपेटो करने की कोशिश कर अजगर उपयोगकर्ताओं के लिए रुचि का हो सकता प्रदान की ..

मैं दूसरी तरफ से आया था: मैं पहले से ही आर्किबजेक्ट्स को लंबे (लंबे समय तक) जानता था, इससे पहले कि मैंने अजगर के बारे में भी सुना था और इन जैसे पदों के लिए धन्यवाद, मैं अजगर की आसान पटकथा में कुछ महत्वपूर्ण आर्कबोज शामिल करने में सक्षम हूं ( उदाहरण के लिए इस पोस्ट को देखें )। मुझे विरासत, तरीकों और गुणों को समझने की कोशिश करने की हताशा याद है; दुविधा की तरह मुझे X मिला है जो Y से संबंधित है ... तो मैं X से Y.Method () से कैसे प्राप्त करूं?

इसका जवाब यह है कि इंटरफ़ेस को लागू करने वाले CoClasses को देखें (यहां पूर्ण पाठ देखें ) .. एक मूल उदाहरण के लिए, अगर मैं यह देखना चाहता हूं कि क्या किसी परत की परिभाषा क्वेरी है, और यदि ऐसा है तो:

C # में:

ILayer pLayer = pMap.get_Layer(LayerIndex);
IFeatureLayer pFtLayer = pLayer as IFeatureLayer; // also written pFtLayer = (IFeatureLayer) pLayer
IFeatureLayerDefinition pFtLayDef = (IFeatureLayerDefinition)pFtLayer; // also works as pFtLayDef = pFtLayer as IFeatureLayerDefinition;
if (pFtLayDef.DefinitionExpression.Length == 0)
    Console.WriteLine("No definition query");
else
    Console.WriteLine("Query is " + pFtLayDef.DefinitionExpression);

इसके बजाय ctype(जो VB में प्रमुख है) C # का उपयोग करता है ()या asकास्टिंग के लिए, उदाहरण के IObject x = (IObject)y;लिए (मौलिक रूप से) वही है IObject x = y as IObject;जो dim x as IObject = ctype(y,IObject)VB में होगा ।

मैं बता सकता है कि मैं एक की जरूरत है IFeatureLayer को पाने के लिए IFeatureLayerDefinition है क्योंकि: यहां छवि विवरण दर्ज करें

और जब आप IFeatureLayer के लिए सहायता दस्तावेज़ देखते हैं तो आप देखते हैं: यहां छवि विवरण दर्ज करें

जो इंगित करता है कि ILayer-> IFeatureLayer-> IFeatureLayerDef पर जाना सुरक्षित है, बशर्ते कि ILayer फ़ीचरलेयर (या किसी अन्य CoClasses) का हो।

तो क्या मैं और मैं के साथ नहीं है? I का अर्थ है इंटरफ़ेस, यह बिट है जो काम करता है, I के बिना एक CoClass (एक प्रकार ) है, इसलिए कुछ भी जो आप वास्तव में उपयोग करना चाहते हैं, एक I से शुरू होना चाहिए और यदि आप एक नया बना रहे हैं या प्रकार की जाँच कर रहे हैं I. छोड़ें I. एक इंटरफ़ेस में कई CoClasses हो सकते हैं और एक CoClass कई इंटरफेस का समर्थन कर सकता है लेकिन यह इंटरफ़ेस है जो वास्तव में काम करता है।

अजगर में:

# I'm assuming arcpy is already imported and comtypes installed
from comtypes.client import GetModule, CreateObject
mC = GetModule(r'C:\Your path\Desktop10.1\com\esriCarto.olb')
mU = GetModule(r'C:\Your path\Desktop10.1\com\esriArcMapUI.olb')
mF = GetModule(r"C:\Your path\Desktop10.1\com\esriFramework.olb")

import comtypes.gen.esriCarto as esriCarto
import comtypes.gen.esriFramework as esriFramework
import comtypes.gen.esriArcMapUI as esriArcMapUI

app = CreateObject(mF.AppROT, interface=mF.IAppROT) # a reference to the ArcMap application
pDoc = ctype(app.Item(0).Document,mU.IMxDocument)   # a reference to the current document
pMap = pDoc.FocusMap # the currently active map
pLayer = pMap.get_layer(LayerIndex)
pFtLayer = ctype(pLayer,esriCarto.IFeatureLayer)
pFtLayDef = ctype(pFtLayer,esriCarto.IFeatureLayerDefinition)
if len(pFtLayDef.DefinitionExpression) == 0:
    print("No definition expression")
else:
    print("Query is " + pFtLayDef.DefinitionExpression)

यह नमूना C से थोड़ा अधिक है कि यह वर्तमान एप्लिकेशन के लिए अपना रास्ता ढूंढता है, जो केवल पायथन विंडो या एक ऐडिन में उपलब्ध होगा, यदि आपने इसे कमांड लाइन से चलाने की कोशिश की है तो एप्लिकेशन अशक्त है और स्क्रिप्ट तब होगी एक शून्य संदर्भ अपवाद के साथ दुर्घटना।


वाह, इस पोस्ट करने के लिए बहुत बहुत धन्यवाद! आर्कोबजेक्ट डायग्राम्स को समझने में मुझे कुछ संघर्ष करना पड़ा है। अपने जैसे किसी व्यक्ति से कुछ इनपुट लेना अच्छा है, जो बाड़ के दूसरी तरफ से आता है (बहुत से .NET आर्कोबजेक्ट्स का अनुभव)। एक बात जो मुझे कुछ परेशानियों में डालती है, वह है एक फीचर क्लास को एक्सेस करना जो कॉमिक और पायथन के माध्यम से फीचर डेटासेट में रहता है। मुझे लगता है कि अतीत में मैंने पहले फीचर डेटा सेट को खोलने की कोशिश की है और फिर फीचर क्लास को बनाया है, लेकिन कोई भी भाग्य नहीं मिला है (कुछ अशक्त संकेत प्राप्त कर रहा है)। क्या आपके पास उसके लिए कोई अजगर के नमूने हैं?
crmackey

1
इतना नहीं, मैं वास्तव में केवल अजगर में कॉमपाइप के साथ शुरू कर रहा हूं, लेकिन कार्यक्षेत्र (IFeatueWorkspace) ऑब्जेक्ट से एक फीचर क्लास खोलने के लिए केवल नाम का उपयोग करें, फीचर डेटासेट को बिल्कुल भी शामिल न करें - इससे कोई फर्क नहीं पड़ता यह एक सुविधा डेटासेट में है, सभी नाम अद्वितीय हैं ... help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/… देखें क्या आप कुछ कोड के साथ एक नया प्रश्न खोल सकते हैं और मेरे पास एक नज़र होगा। डेटासेट का उपयोग डेटासेट (IFeatureDataset.Subsets) की सुविधा के साथ किया जा सकता है, लेकिन यह केवल नाम के साथ खुला है।
माइकल स्टिमसन

1
थैंक्स @ मिकाइल माइल्स-स्टिम्सन। मैं इसे एक और शॉट दूंगा। अगर मैं इसका पता नहीं लगा पाया, तो मैं अपने वर्तमान कोड के साथ एक नया प्रश्न पोस्ट करूंगा।
crmackey

@MichaelStimson मैं समझता हूं कि मैं कॉम्पीटिस का उपयोग करके अजगर में आर्कोबेजेक्ट्स का उपयोग कर सकता हूं। मैंने कभी भी आर्कोबिज का उपयोग नहीं किया है। यह देखते हुए कि कार्य करने के लिए कहीं भी नमूने नहीं हैं, जैसे कॉम्पटियों और आर्कपी का उपयोग करके नेटवर्क डेटासेट का निर्माण करना, क्या मुझे कॉम्पीप्स का उपयोग करने से पहले आर्कबजेक्ट को समझने की आवश्यकता है? या मैं सिर्फ चापलूसी और हास्य का उपयोग करने के लिए खुद से कॉम्टेप्स सीख सकता हूं?
केतुर

1
@ देवदार, जब आप उन्हें अजगर में इस्तेमाल करने की कोशिश करते हैं, तो आर्कोबजेक्ट्स के बारे में थोड़ा जानना अच्छा होता है। हालांकि वहां अजगर में ArcObjects के कई नमूने नहीं हैं (अभी तक) वहाँ की तरह ArcObjects मदद में नमूने हैं resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/... नेटवर्क डेटासेट के लिए (निर्माण कि का अंतिम आइटम पृष्ठ)। आर्कऑब्जेक्ट्स कोड अजगर (आर्कपी) की तुलना में काफी अधिक क्रिया है; व्यक्तिगत रूप से मैं VB या C # में कोड करूँगा और फिर जब परिणाम से खुश हो जाएगा / python में पेस्ट कर देगा।
माइकल स्टिम्सन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.