我希望能够编写一些无法通过arcgisscripting或ArcPy公开的内容。

如何从Python访问ArcObjects?

评论

是否有人想过在生产环境中使用这些方法?几年前,我在UC上与一位ESRI C ++开发人员进行了交谈,他们开发了他们的大多数Python模块,他强烈反对在生产环境中使用IronPython,但这是几年前的事情。

#1 楼

下载并安装comtypes *,将Mark Cederholm的Snippets模块放入PYTHONPATH中,一切就绪。

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


有关背景信息,请参阅Mark Cederholm为UberPyGeeks所作的“在Python中使用ArcObjects”的演示。对于VBA和C ++开发人员而言,有单独的观点。他们使用Visual Studio(可以使用Express)和Windows SDK,但这不是必需的,仅ArcGIS,Python和comtypes就足够了。

获取代码片段模块



10.0-http://www.pierssen.com/arcgis10/upload/ python / snippets100.py

10.1-http://www.pierssen.com/arcgis10/upload/python/snippets101.py

10.2-http:// www。 pierssen.com/arcgis10/upload/python/snippets102.py


*请注意,对于10.1+,需要在comtypes模块中对automation.py进行少量更改。
请参阅ArcObjects。 +转换为10.1。


下一步...

...或:大脑变得蛇行?看一下C#代码示例会让您大吃一惊,然后尝试尝试一下,就像只是无法像起重机一样思考?在这里查看:


从Python使用ArcObjects的指南
ArcObjects入门?
ArcObjects资源


评论


这个话题已经引起我的注意,似乎有一些误解。您不需要Visual Studio或MIDL编译器即可在Python中使用ArcObjects。您需要的只是comtypes包。我的演讲包括使用Python创建COM组件的高级练习,但这是针对UberPyGeeks的。 snippets.py文件包含您需要的所有示例。

–user2715
2011年4月18日在14:39

@Mark,非常感谢您的纠正。需要说明的是:在上述配方中,只要已经安装了ctypes,就可以删除步骤1、3、4。

–马特·威尔基
2011年4月18日在17:15

是的在实验室测试过。您只需要安装comtypes。

– R.K.
2012-2-5 14:34

@ R.K。,太好了!感谢您的验证并提供最新答案。

–马特·威尔基
2012年2月6日在17:09

片段模块在此处可重装为可安装的ao模块:github.com/maphew/arcplus/tree/master/arcplus/ao(已更新为10.3,有关10.2,请参见文件的先前版本)。一旦发现一些错误,便会更新主要答案。

–马特·威尔基
2015年1月7日在23:51

#2 楼

是的,Matt Wilkie上面提到的Mark Cederholm的演讲是一个很好的起点。 Matt提出的配方/代码无疑是一种巧妙的方法,并且可能是解决问题的最佳方法。不过,我想提一下我在ArcGIS 10.0中使用的蛮力方法。我有几种以这种方式运行的自动化脚本(独立于应用程序边界),它们可以正常工作。但是,如果要考虑最大速度,则可以使用Matt的解决方案并完成它。

我使用comtypes包来强制包装所有ArcObjects库(.olb)。然后,Python可以访问所有ArcObjects。我通过ESRI论坛帖子从Frank Perks获得了包装代码。我有自己的代码,基本上执行了相同的操作,但是它肿且仅能起作用,而他的代码更漂亮。所以:

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)


然后,很明显是Mark Cederholm的介绍:您应该具有对ArcObjects的完全访问权限,从pRef对象(即AppRef对象上的IApplication)开始。以我的经验,第一次运行时对ArcObjects库的包装并不令人讨厌,并且在后续运行中也不会发生包装。这些库已经被包装和编译,因此速度更快。

已添加:
随之而来的是一个很大的警告。此处给出的NewObj函数假定Python脚本正在进程内运行。如果不是,此函数将在Python进程(即进程外)中创建对象,并且对象引用将是错误的。要从外部Python脚本创建过程中对象,应使用IObjectFactory。有关更多信息,请参见此stackexchange帖子中的Kirk Kuykendall的评论和提示。

评论


这种方法的好处是它不需要安装Visual Studio,如果您唯一要做的就是注册com对象,则这是相当重量的。如果我知道这种纯python方法,那么我可能从未尝试过Cederholm的路线。 ;-)

–马特·威尔基
2011年1月10日下午6:14

我在这个答案中对这个概念做了一些扩展,使导入和包装类型库成为一个一步的过程:gis.stackexchange.com/questions/5017/…

–blah238
2011年1月12日23:05

#3 楼


如何从python访问arcobjects?

如果您要查找的是C ++ Arcobjects代码中存在的特定功能,那么最好的选择就是创建C ++方法来调用它们。...,然后创建一个python包装器来访问这些C ++方法。
有很多方法可以从python访问C ++方法,并且很多人使用SWIG之类的工具来自动执行从C ++方法签名生成python类。根据我的经验,这些自动生成的API在传递非本机C ++类型(int,float)时会变得非常讨厌,并且永远不会变得“ pythonic”。
我建议的解决方案是使用ctypes API。一个很棒的教程在这里:http://python.net/crew/theller/ctypes/tutorial.html
基本步骤是:

用C ++编写一些核心逻辑,您认为python性能可能是一个问题的
使用任何系统将核心逻辑(在这种情况下,使用ArcObject C ++ API方法调用)从对象文件编译为共享(.so)或动态库(.dll)编译器(nmake,make等)
在python类和C ++方法签名之间写一个ctypes映射[SWIG试图使之自动化,但这很容易,即使使用疯狂的对象类型也是如此]
将库编译到您的python程序中,并像其他任何python类一样使用绑定的类/方法绑定!

这可能是从python内部引用C / C ++代码的更通用的方法,从长远来看,如果您不必处理COM对象,则要简单得多。它还将允许所有特定于系统的功能驻留在链接库对象的编译中(因此python将不是特定于系统/ python实现的)。

评论


这无疑是与ArcObjects进行交互的最佳方法。使用comtypes非常适合用于原型制作,但是编写自己的C扩展将导致良好的Pythonic设计(因为您必须考虑它)和更好的性能,因为您不会越过C ++ / Python对象障碍。尽管出于实际目的,这更难于设计/开发/调试,所以快捷便不在了。

–Jason Scheirer
2011年2月3日,下午1:08

#4 楼

另一个选择是将Python用于.NET,这是非常容易设置的,并且可以与包括ArcObjects在内的任何.NET DLL一起使用。

我在处理过程中的对象方面没有遇到任何问题,因此打开ArcMap实例以及添加和操作图层对我来说很好。

唯一的要求是包含Python for .NET库的文件夹和标准的Python安装。

更多详细信息和示例脚本在这里。还可以直接在http://gist.github.com/923954

上看到示例脚本,尽管此脚本在本地开发计算机上没有问题,但将其部署到其他地方则需要ArcObjects SDK,并且将要安装Visual Studio(包括免费的Express版)。请参阅部署ArcObject .NET DLL

评论


食谱清晰,明了且讲究。感谢Geographika!我鼓励您在回答中包含一个最小的脚本片段,以便在您的网站进行翻新的情况下,回答可以独立存在。

–马特·威尔基
2011年6月6日22:55

这正是我在此旧博客文章(gissolved.blogspot.com/2009/06/python-toolbox-3-pythonnet.html)中所做的工作,它可以按预期工作,但请确保返回您的Python脚本可以理解的结果(字符串,数字)或无效)。

–塞缪尔
2011-12-20 9:06



链接geographika.co.uk/using-arcobjects-and-net-in-python损坏。

– SIslam
15年8月4日在6:12

#5 楼

在其他答案中没有提到的一种方法是使用与arcpy库本身使用的方法相同的方法。例如。在C:\ Program Files \ ArcGIS \ Desktop10.0 \ arcpy \ arcpy \ cartography.py中,我们看到Python使用一些fixargs和对象转换函数来调用ArcObjects工具。

我不知道它有多少可以在此处发布它,因为代码显示为“交易秘密:ESRI专有和机密”;但您也可以在网络上的其他地方找到它。无论如何,这看起来像调用SimplifyBuilding_cartography()之类的函数的相对简单的方法,而无需安装comtypes或任何其他额外的库。听起来像做上面的事不会买很多东西。

评论


我也注意到了,但似乎也太多了。

–blah238
13年1月25日在17:39

它不是在调用完全公开的arcobjects集。

–Jason Scheirer
13年1月25日在17:53

@JasonScheirer,尽管如此,它显然允许比直接arcpy API更大程度的访问ArcObjects(我认为),并且它的优点是不需要安装其他库。如果您正在开发供其他人使用的工具,则后者可能很重要。我想知道您可以通过这种方法访问的内容的全部范围,对于某些用途来说可能就足够了。 (我现在无法检查-我不在公司的LAN上。)

– LarsH
2013年1月25日19:24



我可以向您保证事实并非如此。我开发了很多。

–Jason Scheirer
13年1月25日在20:14

你不能。在这种情况下,“ ArcObject”有点用词不当。无法访问基础对象,也没有COM绑定将所有ArcObjects暴露在arcgisscripting / arcpy中的任何位置。

–Jason Scheirer
13年1月25日在22:00