J'aimerais pouvoir arcgisscripting
créer un script pour certaines choses qui ne sont pas exposées via ou ArcPy.
Comment accéder à ArcObjects à partir de Python?
J'aimerais pouvoir arcgisscripting
créer un script pour certaines choses qui ne sont pas exposées via ou ArcPy.
Comment accéder à ArcObjects à partir de Python?
Réponses:
Téléchargez et installez les types *, mettez le Snippets
module de Mark Cederholm dans PYTHONPATH, et le tour est joué.
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
Pour en savoir plus, reportez-vous aux présentations de Mark Cederholm pour UberPyGeeks sur "Utilisation d’ArcObjects en Python" . Il en existe différents pour les perspectives de développement VBA et C ++. Ils utilisent Visual Studio (oui Express est ok) et le Kit de développement logiciel (SDK) Windows , mais ils ne sont pas obligatoires. Seuls ArcGIS, Python et les types de caractères suffisent.
* Remarque pour 10.1+ vous devez apporter une petite modification automation.py
dans le module comtypes. Voir les types de types ArcObjects + à la section 10.1 .
... ou: le cerveau est devenu sournois ? En regardant les exemples de code c #, vos yeux vont nager et vous ne pouvez pas penser comme une grue . Regardez ici:
Oui, l'exposé de Mark Cederholm mentionné par Matt Wilkie est un excellent point de départ. La recette / le code présenté par Matt est certainement une excellente solution et constitue probablement la meilleure façon de procéder. Je voulais toutefois mentionner la méthode de force brute que j'utilise dans ArcGIS 10.0. J'ai plusieurs scripts d'automatisation (autonomes, en dehors des limites de l'application) que je lance de cette façon et ils fonctionnent parfaitement. Si la vitesse maximale vous préoccupe, vous pouvez simplement choisir la solution de Matt et en finir.
J'utilise le package comtypes pour forcer le wrapping de toutes les bibliothèques ArcObjects (.olb). Ensuite, Python a accès à tous les ArcObjects. Le code d’emballage de Frank Perks m’a été envoyé sur un forum ESRI . J'avais mon propre code qui faisait essentiellement la même chose, mais il était gonflé et simplement fonctionnel, alors que le sien est beaucoup plus joli. Alors:
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)
Ensuite, assez directement dans la présentation 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
C'est ça. Vous devriez avoir un accès complet à ArcObjects à partir de l'objet pApp qui est IApplication sur l'objet AppRef. D'après mon expérience, l'encapsulation des bibliothèques ArcObjects lors de la première exécution n'est pas trop lente, et pour les exécutions suivantes, l'encapsulation n'a pas lieu. Les bibliothèques sont déjà encapsulées et compilées, ce qui accélère considérablement les choses.
Ajouté: Il y a une grande prudence qui vient avec cela. La fonction NewObj donnée ici suppose que le script Python est en cours d'exécution. Sinon, cette fonction créera des objets dans le processus Python (c.-à-d. Hors processus) et les références aux objets seront fausses. Pour créer des objets en cours à partir d'un script Python externe, vous devez utiliser IObjectFactory. Voir les commentaires et astuces de Kirk Kuykendall dans cet article stackexchange pour plus d'informations.
Comment accéder aux arcobjects depuis python?
Si vous recherchez des fonctionnalités spécifiques existantes dans le code Arcobjects C ++, il est conseillé de créer des méthodes C ++ pour les appeler, puis de créer un wrapper python pour accéder à ces méthodes C ++.
Il existe de nombreuses façons d'accéder aux méthodes C ++ à partir de python, et beaucoup de personnes qui le font utilisent un outil tel que SWIG pour générer automatiquement les classes python à partir des signatures de méthodes C ++. D'après mon expérience, ces API générées automatiquement sont plutôt méchantes lorsqu'elles transmettent des types C ++ non natifs (int, floats) et ne sont jamais très " pythoniques ".
Ma solution recommandée serait d'utiliser l'API ctypes. Un excellent tutoriel est ici: http://python.net/crew/theller/ctypes/tutorial.html
Les étapes de base sont les suivantes:
C’est probablement une façon plus générale de référencer le code C / C ++ à partir de python. Cela sera probablement beaucoup plus simple à long terme si vous n’avez pas à traiter avec des objets COM. Cela permettra également à toutes les fonctionnalités spécifiques du système de résider dans la compilation de l'objet de bibliothèque lié (le python ne sera donc pas spécifique à l'implémentation système / python).
Une autre option consiste à utiliser Python pour .NET . Il est très facile à configurer et peut fonctionner avec toutes les DLL .NET, y compris ArcObjects.
Je n'ai rencontré aucun problème d'objet en cours de processus, et l'ouverture d'une instance d'ArcMap et l'ajout et la manipulation de couches ont bien fonctionné pour moi.
Les seules conditions requises sont un dossier contenant la bibliothèque Python pour .NET et une installation Python standard.
Plus de détails et exemple de script ici . L'exemple de script est également visible directement à l' adresse http://gist.github.com/923954.
Malheureusement, bien que cela fonctionne sans problème sur une machine de développement locale, son déploiement ailleurs nécessite l'installation du SDK ArcObjects et de Visual Studio (y compris l'édition Express gratuite). Voir Déploiement de DLL ArcObject .NET
Une approche que je ne vois pas mentionnée dans les autres réponses consiste à utiliser les mêmes méthodes que celles utilisées par les bibliothèques arcpy. Par exemple, dans C: \ Program Files \ ArcGIS \ Desktop10.0 \ arcpy \ arcpy \ cartography.py, nous voyons Python appeler des outils ArcObjects à l'aide de fixargs et de fonctions de conversion d'objet.
Je ne sais pas combien il est acceptable de poster à ce sujet ici, car le code dit "SECRETS COMMERCIAUX: ESRI PROPRIÉTAIRE ET CONFIDENTIEL"; mais vous le trouverez ailleurs sur le Web. Quoi qu’il en soit, cela semble être un moyen relativement facile d’appeler des fonctions, SimplifyBuilding_cartography()
sans installer de types de caractères ou d’autres bibliothèques supplémentaires.
Modifier:
Voir les commentaires de Jason ci-dessous. On dirait que faire ce qui précède ne vous achètera pas beaucoup.