Eu gostaria de poder criar scripts para algumas coisas que não são expostas via arcgisscripting
ou ArcPy.
Como acesso o ArcObjects a partir do Python?
Eu gostaria de poder criar scripts para algumas coisas que não são expostas via arcgisscripting
ou ArcPy.
Como acesso o ArcObjects a partir do Python?
Respostas:
Baixe e instale comtypes *, coloque o Snippets
módulo de Mark Cederholm em PYTHONPATH e está tudo pronto.
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 mais informações, consulte as apresentações de Mark Cederholm para o UberPyGeeks em "Usando o ArcObjects em Python" . Existem outros para as perspectivas do desenvolvedor de VBA e C ++. Eles usam o Visual Studio (sim, Express está ok) e o Windows SDK , mas eles não são necessários, apenas ArcGIS, Python e comtypes são suficientes.
* Observe que para 10.1+ você precisa fazer uma pequena alteração automation.py
no módulo comtypes. Veja ArcObjects + comtypes em 10.1 .
... ou: cérebro enlouquecido ? Olhar para os exemplos de código c # faz com que seus olhos nadem e tente da mesma maneira que você não consegue pensar como um guindaste ? Olhe aqui:
Sim, a apresentação de Mark Cederholm que Matt Wilkie menciona acima é um ótimo lugar para começar. A receita / código que Matt apresenta é certamente uma mancha e provavelmente a melhor maneira de fazer as coisas. Eu queria mencionar, no entanto, o método de força bruta que estou usando no ArcGIS 10.0. Tenho vários scripts de automação (autônomos, fora do limite do aplicativo) que são executados dessa maneira, e eles funcionam muito bem. Se a velocidade máxima é uma preocupação, no entanto, você pode simplesmente optar pela solução de Matt e terminar com ela.
Eu uso o pacote comtypes para forçar a quebra de todas as bibliotecas do ArcObjects (.olb). Então, o Python tem acesso a todos os ArcObjects. Eu recebi o código de embalagem de Frank Perks através de uma postagem no fórum da ESRI . Eu tinha meu próprio código que essencialmente fazia a mesma coisa, mas era inchado e meramente funcional, enquanto o dele é muito mais bonito. Assim:
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)
Então, praticamente direto da apresentação 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
É isso aí. Você deve ter acesso total ao ArcObjects começando com o objeto pApp que é IApplication no objeto AppRef. Na minha experiência, o agrupamento das bibliotecas do ArcObjects na primeira execução não é objetivamente lento e, para execuções subsequentes, o agrupamento não acontece. As bibliotecas já estão agrupadas e compiladas, portanto as coisas são muito mais rápidas.
Adicionado: há um grande cuidado que vem com isso. A função NewObj fornecida aqui assume que o script Python está sendo executado no processo. Caso contrário, essa função criará objetos no processo Python (ou seja, fora de processo) e as referências a objetos estarão erradas. Para criar objetos de processo a partir de um script Python externo, você deve usar IObjectFactory. Veja os comentários e dicas de Kirk Kuykendall nesta postagem de stackexchange para obter mais informações.
Como faço para acessar arcobjects a partir de python?
Se o que você está procurando é uma funcionalidade específica que existe e está no código de objetos C ++, sua melhor aposta seria criar métodos C ++ para chamá-los ... e criar um wrapper python para acessar esses métodos C ++.
Existem várias maneiras de acessar métodos C ++ a partir de python, e muitas pessoas usam uma ferramenta como SWIG para gerar automaticamente as classes python a partir das assinaturas do método C ++. Tem sido minha experiência que essas APIs geradas automaticamente ficam bastante desagradáveis ao passar tipos C ++ não nativos (int, floats) e nunca são muito ' pitônicas '.
Minha solução recomendada seria usar a API ctypes. Um ótimo tutorial está aqui: http://python.net/crew/theller/ctypes/tutorial.html
Os passos básicos são:
Essa é provavelmente a maneira mais geral de fazer referência ao código C / C ++ no python; provavelmente será muito mais simples a longo prazo, se você não precisar lidar com objetos COM. Também permitirá que toda a funcionalidade específica do sistema resida na compilação do objeto de biblioteca vinculada (para que o python não seja específico da implementação do sistema / python).
Outra opção é usar o Python para .NET - isso é muito fácil de configurar e pode funcionar com qualquer DLL do .NET, incluindo o ArcObjects.
Não tive problemas com defeitos no processo, e abrir uma instância do ArcMap e adicionar e manipular camadas funcionou bem para mim.
Os únicos requisitos são uma pasta que contém a biblioteca Python para .NET e uma instalação padrão do Python.
Mais detalhes e exemplo de script aqui . O script de exemplo também pode ser visto diretamente em http://gist.github.com/923954
Infelizmente, embora isso funcione sem problemas em uma máquina de desenvolvimento local, sua implantação em outros lugares exige a instalação do ArcObjects SDK e do Visual Studio (incluindo a edição gratuita do Express). Consulte Implantando DLLs do ArcObject .NET
Uma abordagem que não vejo mencionada nas outras respostas é usar os mesmos métodos usados pelas próprias bibliotecas do arcpy. Por exemplo, em C: \ Arquivos de programas \ ArcGIS \ Desktop10.0 \ arcpy \ arcpy \ cartography.py, vemos o Python chamando as ferramentas do ArcObjects usando algumas funções de conversão de objetos e fixargs.
Não sei quanto postar sobre isso aqui, já que o código diz "SEGREDOS DO COMÉRCIO: ESRI PROPRIETÁRIOS E CONFIDENCIAIS"; mas você também o encontrará em outros lugares da web. De qualquer forma, parece uma maneira relativamente fácil de chamar funções, SimplifyBuilding_cartography()
sem instalar tipos ou qualquer outra biblioteca extra.
Editar:
Veja os comentários de Jason abaixo. Parece que fazer o exposto acima não lhe comprará muito.