Saya ingin dapat skrip beberapa hal yang tidak diekspos melalui arcgisscripting
atau ArcPy.
Bagaimana cara mengakses ArcObjects dari Python?
Saya ingin dapat skrip beberapa hal yang tidak diekspos melalui arcgisscripting
atau ArcPy.
Bagaimana cara mengakses ArcObjects dari Python?
Jawaban:
Unduh dan pasang comtypes *, masukkan Snippets
modul dari Mark Cederholm di PYTHONPATH, dan Anda siap.
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
Untuk latar belakang lihat presentasi Mark Cederholm untuk UberPyGeeks tentang "Menggunakan ArcObjects dengan Python" . Ada yang terpisah untuk perspektif pengembang VBA dan C ++. Mereka menggunakan Visual Studio (yes Express ok) dan Windows SDK , tetapi ini tidak diperlukan, hanya ArcGIS, Python dan comtypes sudah cukup.
* Catatan untuk 10.1+ Anda perlu membuat perubahan kecil automation.py
pada modul comtypes. Lihat ArcObjects + comtypes di 10.1 .
... atau: otaknya menjadi berliku ? Melihat contoh kode c # membuat mata Anda berenang, dan berusaha sekuat tenaga Anda tidak bisa berpikir seperti burung bangau ? Lihat di sini:
Ya, presentasi Mark Cederholm yang disebutkan Matt Wilkie di atas adalah tempat yang bagus untuk memulai. Resep / kode yang disajikan Matt tentu saja licin dan mungkin cara terbaik untuk menyelesaikan masalah. Saya ingin menyebutkan, metode yang agak kasar yang saya gunakan di ArcGIS 10.0. Saya memiliki beberapa skrip otomatisasi (mandiri, di luar batas aplikasi) yang saya jalankan dengan cara ini, dan mereka berfungsi dengan baik. Namun, jika kecepatan maksimum menjadi perhatian, Anda mungkin hanya pergi dengan solusi Matt dan selesai dengan itu.
Saya menggunakan paket comtypes untuk memaksa pembungkus semua perpustakaan ArcObjects (.olb). Kemudian Python memiliki akses ke semua ArcObjects. Saya mendapat kode pembungkus dari Frank Perks melalui posting forum ESRI . Saya memiliki kode sendiri yang pada dasarnya melakukan hal yang sama, tetapi itu membengkak dan hanya berfungsi, sementara itu jauh lebih cantik. Begitu:
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)
Kemudian, langsung dari presentasi 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
Itu dia. Anda harus memiliki akses penuh ke ArcObjects yang dimulai dengan objek pApp yaitu IApplication pada objek AppRef. Dalam pengalaman saya, pembungkus pustaka ArcObjects pada proses pertama tidak terlalu lambat, dan untuk proses selanjutnya pembungkus tidak terjadi. Perpustakaan sudah dibungkus dan dikompilasi, jadi semuanya jauh lebih cepat.
Ditambahkan: Ada kehati-hatian besar yang datang dengan ini. Fungsi NewObj yang diberikan di sini mengasumsikan skrip Python sedang dijalankan dalam proses. Jika tidak, fungsi ini akan membuat objek dalam proses Python (mis. Proses out-of), dan referensi objek akan salah. Untuk membuat objek dalam proses dari skrip Python eksternal Anda harus menggunakan IObjectFactory. Lihat komentar dan tips Kirk Kuykendall dalam posting pertukaran stack ini untuk info lebih lanjut.
Bagaimana cara mengakses arcobjects dari python?
Jika yang Anda cari adalah fungsionalitas khusus yang ada dan ada dalam kode Arcobject C ++, maka taruhan terbaik Anda adalah membuat metode C ++ untuk memanggil mereka .... dan kemudian membuat pembungkus python untuk mengakses metode C ++ tersebut.
Ada beberapa cara untuk mengakses metode C ++ dari python, dan banyak orang yang melakukannya menggunakan alat seperti SWIG untuk secara otomatis menghasilkan kelas-kelas python dari tanda tangan metode C ++. Sudah pengalaman saya bahwa API autogenerasi ini menjadi sangat jahat ketika melewati tipe C ++ non-asli (int, float) dan tidak pernah sangat ' pythonic '.
Solusi saya yang disarankan adalah menggunakan API ctypes. Tutorial yang hebat ada di sini: http://python.net/crew/theller/ctypes/tutorial.html
Langkah-langkah dasarnya adalah:
Ini mungkin cara yang lebih umum untuk referensi kode C / C ++ dari dalam python, mungkin akan jauh lebih sederhana dalam jangka panjang jika Anda tidak harus berurusan dengan objek COM. Ini juga akan memungkinkan semua fungsionalitas sistem khusus berada dalam kompilasi objek pustaka yang ditautkan (sehingga python tidak akan menjadi sistem / implementasi python spesifik).
Pilihan lain adalah dengan menggunakan Python untuk .NET - ini sangat mudah diatur, dan dapat bekerja dengan .NET DLL termasuk ArcObjects.
Saya tidak mengalami masalah dengan obrolan dalam proses, dan membuka instance ArcMap dan menambahkan dan memanipulasi lapisan bekerja dengan baik untuk saya.
Satu-satunya persyaratan adalah folder yang berisi Python untuk .NET library, dan instalasi Python standar.
Lebih detail dan contoh skrip di sini . Contoh skrip juga dapat dilihat langsung di http://gist.github.com/923954
Sayangnya, sementara ini bekerja tanpa masalah pada mesin pengembangan lokal, menyebarkannya di tempat lain membutuhkan ArcObjects SDK, dan Visual Studio (termasuk edisi Express gratis) untuk diinstal. Lihat Menyebarkan ArcObject. NET DLL
Satu pendekatan yang saya tidak lihat disebutkan dalam jawaban lain adalah dengan menggunakan metode yang sama dengan perpustakaan arcpy sendiri. Misalnya dalam C: \ Program Files \ ArcGIS \ Desktop10.0 \ arcpy \ arcpy \ cartography.py, kita melihat Python memanggil alat ArcObjects menggunakan beberapa fixargs dan fungsi konversi objek.
Saya tidak tahu seberapa banyak yang boleh saya posting di sini, karena kode itu mengatakan "RAHASIA DAGANG: PROPRIETER ESRI DAN RAHASIA"; tetapi Anda juga akan menemukannya di tempat lain di web. Bagaimanapun, ini terlihat seperti cara yang relatif mudah untuk memanggil fungsi-fungsi seperti SimplifyBuilding_cartography()
tanpa menginstal comtypes atau perpustakaan tambahan lainnya.
Sunting:
Lihat komentar Jason di bawah ini. Kedengarannya seperti melakukan di atas tidak akan membeli banyak.