Я хотел бы иметь возможность написать некоторые вещи, которые не доступны через arcgisscripting
ArcPy или ArcPy.
Как мне получить доступ к ArcObjects из Python?
Я хотел бы иметь возможность написать некоторые вещи, которые не доступны через arcgisscripting
ArcPy или ArcPy.
Как мне получить доступ к ArcObjects из Python?
Ответы:
Скачайте и установите комтипы *, поместите Snippets
модуль от Марка Седерхолма в PYTHONPATH, и все готово.
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 на тему «Использование ArcObjects в Python» . Есть отдельные для перспектив разработчиков VBA и C ++. Они используют Visual Studio (да, Express в порядке) и Windows SDK , но они не обязательны, достаточно только ArcGIS, Python и compepes.
* Обратите внимание, что для версии 10.1+ необходимо внести небольшое изменение automation.py
в модуль comtypes. Смотрите ArcObjects + comtypes в 10.1 .
... или: мозг сошел с ума ? Глядя на примеры кода на c #, вы поплываете в глаза и стараетесь, как можете, просто не думать как журавль ? Смотри сюда:
Да, презентация Марка Седерхольма, о которой упоминал Мэтт Уилки, - отличное место для начала. Рецепт / код, который представляет Мэтт, безусловно, является хитрым и, вероятно, лучшим способом решения проблем. Я хотел упомянуть, однако, довольно грубый метод, который я использую в ArcGIS 10.0. У меня есть несколько сценариев автоматизации (автономных, вне границ приложения), которые я запускаю таким образом, и они работают просто отлично. Если максимальная скорость вызывает беспокойство, вы можете просто воспользоваться решением Мэтта и покончить с ним.
Я использую пакет comtypes для принудительного переноса всех библиотек ArcObjects (.olb). Затем Python имеет доступ ко всем объектам ArcObject. Я получил упаковочный код от Фрэнка Перкса через публикацию на форуме ESRI . У меня был свой собственный код, который по сути делал то же самое, но он был раздутым и просто функциональным, в то время как его код намного красивее. Так:
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
Вот и все. У вас должен быть полный доступ к объектам ArcObject, начиная с объекта pApp, который является IApplication для объекта AppRef. По моему опыту, оборачивание библиотек ArcObjects при первом запуске не является неожиданно медленным, и для последующих запусков обертывание не происходит. Библиотеки уже упакованы и скомпилированы, так что все намного быстрее.
Добавлено: с этим связана большая осторожность. Функция NewObj, приведенная здесь, предполагает, что скрипт Python выполняется в процессе. Если нет, эта функция будет создавать объекты в процессе Python (т.е. вне процесса), и ссылки на объекты будут неправильными. Для создания в процессе объектов из внешнего скрипта Python вы должны использовать IObjectFactory. См. Комментарии и советы Кирка Куйкендалла в этом стековом сообщении для получения дополнительной информации.
Как я могу получить доступ к arcobjects из python?
Если вам нужна конкретная функциональность, которая существует и присутствует в коде C ++ Arcobjects, то лучше всего было бы создать методы C ++ для их вызова ..., а затем создать оболочку Python для доступа к этим методам C ++.
Существует довольно много способов получить доступ к методам C ++ из python, и многие люди, которые делают это, используют такой инструмент, как SWIG, для автоматической генерации классов python из сигнатур методов C ++. По моему опыту, эти автоматически сгенерированные API-интерфейсы становятся довольно неприятными при передаче не родных типов C ++ (int, float) и никогда не бывают « питонными ».
Мое рекомендуемое решение было бы использовать API ctypes. Отличное учебное пособие здесь: http://python.net/crew/theller/ctypes/tutorial.html
Основные шаги:
Вероятно, это более общий способ ссылаться на код C / C ++ изнутри python, в долгосрочной перспективе, вероятно, будет намного проще, если вам не придется иметь дело с COM-объектами. Это также позволит использовать все специфические для системы функции при компиляции связанного библиотечного объекта (поэтому python не будет зависеть от реализации системы / python).
Другой вариант - использовать Python для .NET - его очень легко настроить, и он может работать с любыми .NET DLL, включая ArcObjects.
У меня не было никаких проблем с внутрипроцессными объектами, и открытие экземпляра ArcMap, добавление и управление слоями работало для меня нормально.
Единственными требованиями являются папка, содержащая библиотеку Python for .NET, и стандартная установка Python.
Более подробная информация и образец сценария здесь . Пример сценария также можно увидеть по адресу http://gist.github.com/923954.
К сожалению, хотя это работает без проблем на локальном компьютере разработки, для его развертывания в другом месте требуется установить ArcObjects SDK и Visual Studio (включая бесплатную редакцию Express). См. Развертывание DLL-библиотек ArcObject .NET.
Один из подходов, о которых я не упоминал в других ответах, - это использование тех же методов, которые используют сами библиотеки arcpy. Например, в C: \ Program Files \ ArcGIS \ Desktop10.0 \ arcpy \ arcpy \ cartography.py, мы видим, что Python вызывает инструменты ArcObjects, используя некоторые фиксаторы и функции преобразования объектов.
Я не знаю, насколько это нормально, чтобы публиковать об этом здесь, так как в коде написано "СЕКРЕТЫ ТОРГОВЛИ: СОБСТВЕННОСТЬ И КОНФИДЕНЦИАЛЬНОСТЬ ESRI"; но вы найдете это и в других местах в Интернете. В любом случае, это выглядит как относительно простой способ вызова функций, например, SimplifyBuilding_cartography()
без установки comtypes или каких-либо других дополнительных библиотек.
Редактировать:
Смотрите комментарии Джейсона ниже. Похоже, что выполнение вышеупомянутого не купит вам много.