Chciałbym mieć możliwość pisania skryptów niektórych rzeczy, które nie są ujawniane za pośrednictwem arcgisscripting
ani ArcPy.
Jak uzyskać dostęp do ArcObjects z Python?
Chciałbym mieć możliwość pisania skryptów niektórych rzeczy, które nie są ujawniane za pośrednictwem arcgisscripting
ani ArcPy.
Jak uzyskać dostęp do ArcObjects z Python?
Odpowiedzi:
Pobierz i zainstaluj typy *, umieść Snippets
moduł od Mark Cederholm w PYTHONPATH i gotowe.
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
W tle zobacz prezentacje Marka Cederholma dla UberPyGeeks na temat „Korzystanie z ArcObjects w Pythonie” . Istnieją osobne perspektywy programistów VBA i C ++. Używają Visual Studio (tak, Express jest w porządku) i Windows SDK , ale nie są one wymagane, wystarczy ArcGIS, Python i typy plików.
* Uwaga dla wersji 10.1+ należy wprowadzić niewielką zmianę automation.py
w module comtypes. Zobacz ArcObjects + comtypes w 10.1 .
... lub: mózg zwariował ? Patrząc na przykłady kodu C # sprawia, że oczy pływać i spróbuj jak to może po prostu nie można myśleć jak dźwigu ? Popatrz tutaj:
Tak, prezentacja Marka Cederholma, o której wspomina Matt Wilkie, jest świetnym miejscem do rozpoczęcia. Przepis / kod, który przedstawia Matt, jest z pewnością sprytnym i prawdopodobnie najlepszym sposobem na załatwienie sprawy. Chciałem jednak wspomnieć o dość brutalnej metodzie, której używam w ArcGIS 10.0. Mam kilka skryptów automatyzacji (autonomicznych, poza granicami aplikacji), które uruchamiam w ten sposób i działają one dobrze. Jeśli jednak chodzi o maksymalną prędkość, możesz po prostu skorzystać z rozwiązania Matta i skończyć z nim.
Korzystam z pakietu comtypes, aby wymusić zawijanie wszystkich bibliotek ArcObjects (.olb). Następnie Python ma dostęp do wszystkich ArcObjects. Otrzymałem kod owijania od Franka Perksa poprzez post na forum ESRI . Miałem własny kod, który zasadniczo robił to samo, ale był nadęty i funkcjonalny, a jego jest ładniejszy. Więc:
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)
Następnie, prawie prosto z prezentacji Marka Cederholma:
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
Otóż to. Powinieneś mieć pełny dostęp do ArcObjects, zaczynając od obiektu pApp, którym jest IApplication na obiekcie AppRef. Z mojego doświadczenia wynika, że owijanie bibliotek ArcObjects przy pierwszym uruchomieniu nie jest obiektywnie powolne, a dla kolejnych uruchomień owijanie nie następuje. Biblioteki są już opakowane i skompilowane, więc wszystko jest znacznie szybsze.
Dodano: Jest z tym duża uwaga. Podana tutaj funkcja NewObj zakłada, że skrypt Pythona jest uruchamiany w trakcie procesu. Jeśli nie, ta funkcja utworzy obiekty w procesie Pythona (tj. Poza procesem), a odwołania do obiektów będą niepoprawne. Aby tworzyć obiekty w procesie z zewnętrznego skryptu Python, należy użyć IObjectFactory. Zobacz komentarze i wskazówki Kirka Kuykendalla w tym poście do wymiany stosów, aby uzyskać więcej informacji.
Jak uzyskać dostęp do obiektów Arcob z Pythona?
Jeśli szukasz konkretnej funkcjonalności, która istnieje i znajduje się w kodzie Arcobjects C ++, najlepiej założyć metody C ++, aby je wywołać .... a następnie utworzyć opakowanie Pythona, aby uzyskać dostęp do tych metod C ++.
Istnieje wiele sposobów uzyskiwania dostępu do metod C ++ z poziomu Pythona, a wiele osób korzysta z takiego narzędzia, jak SWIG, do automatycznego generowania klas Python z sygnatur metody C ++. Z mojego doświadczenia wynika, że te automatycznie generowane interfejsy API stają się dość nieprzyjemne podczas przekazywania nienatywnych typów C ++ (int, float) i nigdy nie są bardzo „ pythoniczne ”.
Moim zalecanym rozwiązaniem byłoby użycie API ctypes. Świetny samouczek jest tutaj: http://python.net/crew/theller/ctypes/tutorial.html
Podstawowe kroki to:
Jest to prawdopodobnie bardziej ogólny sposób odwoływania się do kodu C / C ++ z poziomu Pythona, prawdopodobnie na dłuższą metę będzie prawdopodobnie znacznie prostszy, jeśli nie będziesz musiał zajmować się obiektami COM. Pozwoli to również, aby cała funkcjonalność specyficzna dla systemu znajdowała się w kompilacji połączonego obiektu biblioteki (więc python nie będzie specyficzny dla systemu / implementacji Pythona).
Inną opcją jest użycie Pythona dla platformy .NET - jest to bardzo łatwe do skonfigurowania i może współpracować z dowolnymi bibliotekami DLL .NET, w tym ArcObjects.
Nie spotkałem się z żadnymi problemami z obiektami w trakcie procesu, a otwarcie instancji ArcMap oraz dodawanie i manipulowanie warstwami działało dla mnie dobrze.
Jedyne wymagania to folder zawierający bibliotekę Python dla .NET i standardowa instalacja Pythona.
Więcej informacji i przykładowy skrypt tutaj . Przykładowy skrypt można również zobaczyć bezpośrednio na stronie http://gist.github.com/923954
Niestety, chociaż działa to bez problemów na lokalnym komputerze programistycznym, wdrożenie go w innym miejscu wymaga zainstalowania ArcObjects SDK i Visual Studio (w tym darmowej wersji Express). Zobacz Wdrażanie bibliotek DLL ArcObject .NET
Jedno podejście, którego nie widzę wspomniane w innych odpowiedziach, polega na użyciu tych samych metod, których używają same biblioteki Arcpy. Np. W C: \ Program Files \ ArcGIS \ Desktop10.0 \ arcpy \ arcpy \ cartography.py widzimy Python wywołujący narzędzia ArcObjects przy użyciu niektórych poprawek i funkcji konwersji obiektów.
Nie wiem, jak dobrze jest pisać o tym tutaj, ponieważ kod mówi „TAJEMNICE HANDLOWE: ESRI WŁAŚCIWE I POUFNE”; ale znajdziesz go również w Internecie. W każdym razie wygląda to na stosunkowo łatwy sposób wywoływania funkcji, takich jak SimplifyBuilding_cartography()
bez instalowania typów plików lub innych dodatkowych bibliotek.
Edytować:
Zobacz komentarze Jasona poniżej. Wygląda na to, że wykonanie powyższej czynności nie za wiele kupi.