Tôi muốn có thể viết kịch bản một số thứ không được tiết lộ qua arcgisscripting
hoặc ArcPy.
Làm cách nào để tôi truy cập ArcObjects từ Python?
Tôi muốn có thể viết kịch bản một số thứ không được tiết lộ qua arcgisscripting
hoặc ArcPy.
Làm cách nào để tôi truy cập ArcObjects từ Python?
Câu trả lời:
Tải xuống và cài đặt comtypes *, đặt Snippets
mô-đun từ Mark Cederholm trong PYTHONPATH và bạn đã hoàn tất.
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
Để biết thông tin chi tiết, hãy xem các bài thuyết trình của Mark Cederholm cho UberPyGeek về "Sử dụng ArcObjects trong Python" . Có những cái riêng cho quan điểm của nhà phát triển VBA và C ++. Họ sử dụng Visual Studio (có Express là ok) và SDK Windows , nhưng những thứ này không bắt buộc, chỉ cần ArcGIS, Python và comtypes là đủ.
* Lưu ý cho 10.1+ bạn cần thực hiện một thay đổi nhỏ automation.py
trong mô-đun comtypes. Xem ArcObjects + comtypes tại 10.1 .
... Hoặc: não biến mất ? Nhìn vào các ví dụ mã c # làm cho mắt bạn bơi, và cố gắng như bạn có thể không nghĩ giống như một con sếu ? Nhìn đây:
Vâng, bài thuyết trình của Mark Cederholm mà Matt Wilkie đề cập ở trên là một nơi tuyệt vời để bắt đầu. Công thức / mã mà Matt trình bày chắc chắn là một cách khéo léo và có lẽ là cách tốt nhất để đi về mọi thứ. Mặc dù vậy, tôi muốn đề cập đến phương pháp khá mạnh mẽ mà tôi đang sử dụng trong ArcGIS 10.0. Tôi có một số tập lệnh tự động hóa (độc lập, bên ngoài ranh giới ứng dụng) mà tôi chạy theo cách này và chúng hoạt động tốt. Tuy nhiên, nếu tốc độ tối đa là một mối quan tâm, bạn có thể chỉ cần đi với giải pháp của Matt và được thực hiện với nó.
Tôi sử dụng gói comtypes để buộc gói tất cả các thư viện ArcObjects (.olb). Sau đó, Python có quyền truy cập vào tất cả ArcObjects. Tôi đã nhận được mã gói từ Frank Perks thông qua một bài đăng trên diễn đàn ESRI . Tôi đã có mã riêng của mình về cơ bản đã làm điều tương tự, nhưng nó bị bồng bềnh và chỉ đơn thuần là chức năng, trong khi mã của nó đẹp hơn nhiều. Vì thế:
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)
Sau đó, khá nhiều từ bài thuyết trình của 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
Đó là nó. Bạn nên có quyền truy cập đầy đủ vào ArcObjects bắt đầu với đối tượng pApp là ứng dụng IApplication trên đối tượng AppRef. Theo kinh nghiệm của tôi, việc gói các thư viện ArcObjects trong lần chạy đầu tiên không bị chậm lại một cách khó chịu và đối với các lần chạy tiếp theo, việc gói này không xảy ra. Các thư viện đã được gói và biên dịch, vì vậy mọi thứ nhanh hơn nhiều.
Đã thêm: Có một sự thận trọng lớn đi kèm với điều này. Hàm NewObj được cung cấp ở đây giả sử tập lệnh Python đang được chạy trong quá trình. Nếu không, hàm này sẽ tạo các đối tượng trong quy trình Python (nghĩa là hết quy trình) và các tham chiếu đối tượng sẽ sai. Để tạo các đối tượng xử lý từ tập lệnh Python bên ngoài, bạn nên sử dụng IObjectFactory. Xem ý kiến và lời khuyên của Kirk Kuykendall trong bài đăng trên stackexchange này để biết thêm thông tin.
Làm cách nào để truy cập arcobjects từ python?
Nếu những gì bạn đang tìm kiếm là chức năng cụ thể tồn tại và nằm trong mã C ++ Arcobjects, thì cách tốt nhất của bạn là tạo các phương thức C ++ để gọi chúng .... và sau đó tạo một trình bao bọc python để truy cập các phương thức C ++ đó.
Có khá nhiều cách để truy cập các phương thức C ++ từ python và rất nhiều người sử dụng một công cụ như SWIG để tự động tạo các lớp python từ chữ ký của phương thức C ++. Theo kinh nghiệm của tôi, các API được tạo tự động này trở nên khá khó chịu khi truyền các loại C ++ không bản địa (int, float) và không bao giờ rất ' pythonic '.
Giải pháp được đề xuất của tôi sẽ là sử dụng API ctypes. Một hướng dẫn tuyệt vời có tại đây: http://python.net/crew/theller/ctypes/tutorial.html
Các bước cơ bản là:
Đây có lẽ là cách tổng quát hơn để tham chiếu mã C / C ++ từ bên trong python, về lâu dài có lẽ sẽ đơn giản hơn nhiều nếu bạn không phải xử lý các đối tượng COM. Nó cũng sẽ cho phép tất cả các chức năng cụ thể của hệ thống nằm trong quá trình biên dịch đối tượng thư viện được liên kết (vì vậy python sẽ không được triển khai hệ thống / python cụ thể).
Một tùy chọn khác là sử dụng Python cho .NET - điều này rất dễ thiết lập và có thể hoạt động với bất kỳ DLL .NET nào kể cả ArcObjects.
Tôi đã không gặp phải bất kỳ vấn đề nào với các lỗi trong quá trình và mở ra một phiên bản ArcMap và thêm và thao tác các lớp hoạt động tốt với tôi.
Các yêu cầu duy nhất là một thư mục chứa thư viện Python cho .NET và cài đặt Python chuẩn.
Thêm chi tiết và kịch bản mẫu ở đây . Tập lệnh mẫu cũng có thể được xem trực tiếp tại http://gist.github.com/923954
Thật không may, trong khi điều này hoạt động mà không gặp sự cố trên máy phát triển cục bộ, thì việc triển khai nó ở nơi khác yêu cầu SDK ArcObjects và Visual Studio (bao gồm cả phiên bản Express miễn phí) được cài đặt. Xem Triển khai các tệp .NET ArcObject .NET
Một cách tiếp cận tôi không thấy được đề cập trong các câu trả lời khác là sử dụng các phương thức tương tự mà các thư viện arcpy sử dụng. Ví dụ: trong C: \ Program Files \ ArcGIS \ Desktop10.0 \ arcpy \ arcpy \ cartography.py, chúng tôi thấy Python gọi các công cụ ArcObjects bằng cách sử dụng một số chức năng sửa lỗi và chuyển đổi đối tượng.
Tôi không biết bao nhiêu là ổn để đăng về nó ở đây, vì đoạn mã có nội dung "BÍ MẬT THƯƠNG MẠI: SỞ HỮU VÀ BÍ MẬT ESRI"; nhưng bạn cũng sẽ tìm thấy nó ở nơi khác trên web. Dù sao, đây có vẻ là một cách tương đối dễ dàng để gọi các hàm như SimplifyBuilding_cartography()
không cần cài đặt comtypes hoặc bất kỳ thư viện bổ sung nào khác.
Biên tập:
Xem bình luận của Jason bên dưới. Âm thanh như làm ở trên sẽ không mua cho bạn nhiều.