arcgisscripting
またはArcPy を介して公開されていないもののスクリプトを作成したいと思います。
PythonからArcObjectsにアクセスするにはどうすればよいですか?
arcgisscripting
またはArcPy を介して公開されていないもののスクリプトを作成したいと思います。
PythonからArcObjectsにアクセスするにはどうすればよいですか?
回答:
comtypes *をダウンロードしてインストールしSnippets
、Mark Cederholm のモジュールを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
背景については、「PythonでのArcObjectsの使用」に関するUberPyGeeksに関するMark Cederholmのプレゼンテーションを参照してください。VBAおよびC ++開発者の観点からは、個別のものがあります。彼らは、使用のVisual Studio(はいExpressは OKです)とWindowsのSDKをただのArcGIS、Pythonとcomtypesが十分である、が、これらは必須ではありません。
* 10.1以降の場合automation.py
、comtypesモジュールを少し変更する必要があることに注意してください。10.1のArcObjects + comtypesを参照してください。
...または:頭がおかしくなった?C#コードの例を見ると目が泳いでいるように見えますが、クレーンのように思えないかもしれません。ここを見て:
はい、マット・ウィルキーが上で言及したマーク・セダーホルムのプレゼンテーションは、始めるのに最適な場所です。Mattが提示するレシピ/コードは確かに滑らかで、おそらく物事を進めるための最良の方法です。ただし、ArcGIS 10.0で使用しているブルートフォース方式について言及したかったのです。この方法で実行する自動化スクリプト(スタンドアロン、アプリケーション境界外)がいくつかあり、それらは正常に動作します。ただし、最大速度が懸念される場合は、Mattのソリューションを使用して完了できます。
comtypesパッケージを使用して、すべてのArcObjectsライブラリ(* .olb)を強制的にラップします。これにより、PythonはすべてのArcObjectsにアクセスできます。ESRIフォーラムに投稿して、フランクパークスからラッピングコードを入手しました。基本的に同じことをする独自のコードがありましたが、肥大化しただけで機能的でしたが、彼の方がずっときれいでした。そう:
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のプレゼンテーションからほぼそのまま:
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
それでおしまい。AppRefオブジェクトのIApplicationであるpAppオブジェクトから始まるArcObjectsへのフルアクセスが必要です。私の経験では、最初の実行でのArcObjectsライブラリのラッピングは好ましくないほど遅くなく、その後の実行ではラッピングは発生しません。ライブラリはすでにラップおよびコンパイルされているため、処理ははるかに高速です。
追加: これには大きな注意が必要です。ここで指定するNewObj関数は、Pythonスクリプトがインプロセスで実行されていることを前提としています。そうでない場合、この関数はPythonプロセスでオブジェクトを作成し(アウトプロセス)、オブジェクト参照が間違っています。外部Pythonスクリプトからインプロセスオブジェクトを作成するには、IObjectFactoryを使用する必要があります。詳細については、このstackexchangeの投稿でKirk Kuykendallのコメントとヒントを参照してください。
Pythonからarcobjectsにアクセスするにはどうすればよいですか?
探しているのが、C ++ Arcobjectsコードに存在する特定の機能である場合、最善の策は、C ++メソッドを作成してそれらを呼び出すことです。
PythonからC ++メソッドにアクセスする方法はかなりあります。多くの人は、SWIGなどのツールを使用してC ++メソッドシグネチャからPythonクラスを自動生成しています。私の経験では、これらの自動生成されたAPIは、非ネイティブC ++型(int、float)を渡すときにかなり厄介になり、決して「pythonic」になることはありません。
私の推奨する解決策は、ctypes APIを使用することです。素晴らしいチュートリアルはこちらです:http : //python.net/crew/theller/ctypes/tutorial.html
基本的な手順は次のとおりです。
これはおそらく、Python内からC / C ++コードを参照するより一般的な方法です。COMオブジェクトを処理する必要がない場合、長期的にはおそらくより簡単になるでしょう。また、リンクされたライブラリオブジェクトのコンパイルにシステム固有の機能をすべて許可します(したがって、Pythonはsystem / python実装固有ではありません)。
もう1つのオプションは、Python for .NETを使用することです。これは非常に簡単に設定でき、ArcObjectsを含むすべての.NET DLLで動作します。
インプロセスオブジェクトに関する問題は発生していません。ArcMapのインスタンスを開き、レイヤーを追加および操作することで問題なく動作しました。
唯一の要件は、Python for .NETライブラリを含むフォルダーと、Pythonの標準インストールです。
詳細とサンプルスクリプトこちら。サンプルスクリプトは、http://gist.github.com/923954から直接見ることもできます。
残念ながら、これはローカル開発マシンでは問題なく動作しますが、他の場所に展開するにはArcObjects SDKとVisual Studio(無料のExpressエディションを含む)をインストールする必要があります。ArcObject .NET DLLの展開を参照してください
他の回答で言及されていない1つのアプローチは、arcpyライブラリ自体が使用するのと同じ方法を使用することです。たとえば、C:\ Program Files \ ArcGIS \ Desktop10.0 \ arcpy \ arcpy \ cartography.pyでは、いくつかのfixargsおよびオブジェクト変換関数を使用してPythonがArcObjectsツールを呼び出しています。
コードには「TRADE SECRETS:ESRI PROPRIETARY AND CONFIDENTIAL」と書かれているため、ここに投稿しても大丈夫ではありません。ただし、ウェブ上の他の場所にもあります。とにかく、これはSimplifyBuilding_cartography()
comtypeや他の追加ライブラリをインストールせずに関数を呼び出す比較的簡単な方法のように見えます。
編集:
以下のジェイソンのコメントを参照してください。上記を行うことはあまりあなたを買わないように聞こえます。