Me gustaría poder escribir algunas cosas que no están expuestas a través de arcgisscripting
ArcPy.
¿Cómo accedo a ArcObjects desde Python?
Me gustaría poder escribir algunas cosas que no están expuestas a través de arcgisscripting
ArcPy.
¿Cómo accedo a ArcObjects desde Python?
Respuestas:
Descargue e instale comtypes *, coloque el Snippets
módulo de Mark Cederholm en PYTHONPATH y listo.
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
Para obtener más información, consulte las presentaciones de Mark Cederholm para UberPyGeeks sobre "Uso de ArcObjects en Python" . Hay otros para las perspectivas de desarrollador de VBA y C ++. Usan Visual Studio (sí, Express está bien) y el SDK de Windows , pero no son necesarios, solo ArcGIS, Python y los tipos son suficientes.
* Nota para 10.1+ que necesita hacer un pequeño cambio automation.py
en el módulo de comtypes. Ver ArcObjects + comtypes en 10.1 .
... o: ¿el cerebro se ha vuelto loco ? Mirar los ejemplos del código C # hace que sus ojos naden, e intente como no puede pensar como una grúa . Mira aquí:
Sí, la presentación de Mark Cederholm que Matt Wilkie menciona arriba es un gran lugar para comenzar. La receta / código que presenta Matt es sin duda una buena forma y probablemente la mejor manera de hacer las cosas. Sin embargo, quería mencionar el método de fuerza bruta que estoy usando en ArcGIS 10.0. Tengo varios scripts de automatización (independientes, fuera del límite de la aplicación) que ejecuto de esta manera, y funcionan bien. Sin embargo, si la velocidad máxima es una preocupación, puede optar por la solución de Matt y terminar con ella.
Utilizo el paquete comtypes para forzar el ajuste de todas las bibliotecas de ArcObjects (.olb). Entonces Python tiene acceso a todos los ArcObjects. Recibí el código de Frank Perks a través de una publicación en el foro de ESRI . Tenía mi propio código que esencialmente hacía lo mismo, pero estaba hinchado y meramente funcional, mientras que el suyo es mucho más bonito. Entonces:
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)
Luego, casi directamente de la presentación de Mark Cederholm:
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
Eso es. Debe tener acceso completo a ArcObjects comenzando con el objeto pApp que es IApplication en el objeto AppRef. En mi experiencia, el ajuste de las bibliotecas de ArcObjects en la primera ejecución no es objetivamente lento, y para las ejecuciones posteriores, el ajuste no ocurre. Las bibliotecas ya están envueltas y compiladas, por lo que las cosas son mucho más rápidas.
Agregado: hay una gran precaución que viene con esto. La función NewObj dada aquí asume que el script Python se está ejecutando en proceso. De lo contrario, esta función creará objetos en el proceso de Python (es decir, fuera del proceso), y las referencias a objetos serán incorrectas. Para crear objetos en proceso a partir de un script externo de Python, debe usar IObjectFactory. Vea los comentarios y consejos de Kirk Kuykendall en esta publicación de intercambio de pila para obtener más información.
¿Cómo accedo a los arcobjects desde Python?
Si lo que está buscando es una funcionalidad específica que existe y está en el código de C ++ Arcobjects, entonces su mejor opción sería crear métodos C ++ para llamarlos ... y luego crear un contenedor de Python para acceder a esos métodos C ++.
Hay bastantes maneras de acceder a los métodos C ++ desde Python, y muchas personas que lo hacen usan una herramienta como SWIG para generar automáticamente las clases de Python a partir de las firmas del método C ++. Según mi experiencia, estas API autogeneradas se vuelven bastante desagradables al pasar tipos C ++ no nativos (int, flotantes) y nunca son muy ' pitónicos '.
Mi solución recomendada sería utilizar la API de ctypes. Un gran tutorial está aquí: http://python.net/crew/theller/ctypes/tutorial.html
Los pasos básicos son:
Esta es probablemente la forma más general de hacer referencia al código C / C ++ desde Python, probablemente será mucho más simple a largo plazo si no tiene que lidiar con objetos COM. También permitirá que toda la funcionalidad específica del sistema resida en la compilación del objeto de la biblioteca vinculada (por lo que el Python no será específico de la implementación del sistema / Python).
Otra opción es usar Python para .NET : es muy fácil de configurar y puede funcionar con cualquier DLL de .NET, incluidos ArcObjects.
No he experimentado ningún problema con los obedecimientos en proceso, y abrir una instancia de ArcMap y agregar y manipular capas funcionó bien para mí.
Los únicos requisitos son una carpeta que contenga la biblioteca Python para .NET y una instalación estándar de Python.
Más detalles y script de muestra aquí . El script de muestra también se puede ver directamente en http://gist.github.com/923954
Desafortunadamente, si bien esto funciona sin problemas en una máquina de desarrollo local, la implementación en otro lugar requiere la instalación de ArcObjects SDK y Visual Studio (incluida la edición Express gratuita). Consulte Implementación de archivos DLL de ArcObject .NET
Un enfoque que no veo mencionado en las otras respuestas es usar los mismos métodos que usan las bibliotecas arcpy. Por ejemplo, en C: \ Archivos de programa \ ArcGIS \ Desktop10.0 \ arcpy \ arcpy \ cartography.py, vemos a Python llamando a las herramientas de ArcObjects usando algunos fixargs y funciones de conversión de objetos.
No sé cuánto está bien publicar al respecto aquí, ya que el código dice "SECRETOS COMERCIALES: ESRI PROPIETARIO Y CONFIDENCIAL"; pero también lo encontrarás en otra parte de la web. De todos modos, esto parece una forma relativamente fácil de llamar a funciones como SimplifyBuilding_cartography()
sin instalar comtypes o cualquier otra biblioteca adicional.
Editar:
Vea los comentarios de Jason a continuación. Parece que hacer lo anterior no te comprará mucho.