ArcGIS Desktop

  • ArcGIS Pro
  • ArcMap

  • My Profile
  • ヘルプ
  • Sign Out
ArcGIS Desktop

ArcGIS Online

組織のマッピング プラットフォーム

ArcGIS Desktop

完全なプロ仕様の GIS

ArcGIS Enterprise

エンタープライズ GIS

ArcGIS Developers

位置情報利用アプリの開発ツール

ArcGIS Solutions

各種業界向けの無料のテンプレート マップおよびテンプレート アプリケーション

ArcGIS Marketplace

組織で使えるアプリとデータを取得

  • ドキュメント
  • サポート
Esri
  • サイン イン
user
  • マイ プロフィール
  • サイン アウト

ArcMap

  • ホーム
  • はじめに
  • マップ
  • 解析
  • データ管理
  • ツール
  • エクステンション

スクリプト ツールからの DLL 呼び出し

  • 機能について
  • 詳細情報

ctypes は Python バージョン 2.5 で新規に導入された外部関数ライブラリです。ctypes モジュールは C 互換のデータ タイプを提供し、DLL または共有ライブラリ内の関数の呼び出しを可能にします。Python の ctypes モジュールを使用すると、C++ で記述された ArcObjects コードをジオプロセシング スクリプト ツールで使用できるようになります。

Python の ctypes を使用すると、C++ コードを再コンパイルする必要なく、スクリプト ツールで想定されるパラメーターとタイプを簡単に変更することができます。ctypes モジュールは、char、int、float、double などの基本データ タイプを含む C 呼び出し可能なすべての関数だけでなく、structsとポインターもサポートしています。

Python スクリプトからの DLL 呼び出しには多くのメリットがあります。細分化された ArcObjects クラスをジオプロセシング タスクで利用できるため、知的所有権が保護されます。また、IGPFunction2 インターフェイスや IGPFunctionFactory インターフェイスを使用する必要がある場合と比べて、実装がはるかに容易になっています。オブジェクトを Python で作成し、実行方法を呼び出すと、ジオプロセシング フレームワークを使用するスクリプトから必須パラメーターが渡されます。

機能について

使用手順は次のとおりです。

Visual Studio 2008 で、プロトタイプを示す単純な関数をエクスポートする C++ Win32 プロジェクトを作成します。

int GpExecutetool(char* parameter1, char* parameter2)

必ず ArcGIS\com\directory をプロジェクトに挿入し、ArcObjects *.olb ファイルをインポートしてください。

2 つのパラメーターを整合チェックしてスクリプトに渡すスクリプト ツールをカスタム ツールボックス内に作成します。

作成した Python スクリプトは次のことを実行します。

  • arcpy および ctypes をインポートします。
  • スクリプト ツールからパラメーターを取得
  • DLL をメモリへインポート
  • DLL 内の関数へのポインターを取得
  • argtypes 属性およびリターンのタイプを設定して、DLL からエクスポートされる関数の必須の引数タイプを指定
  • パラメーターを DLL 内の C++ コードに渡す

詳細情報

この C++ プロジェクト (この例では GPToolAsSimpleDLL) は、AREA フィールドをフィーチャクラスへ追加して値を計算する単純な Win32 プロジェクトです。

ヘッダー ファイル

#ifdef GPTOOLASSIMPLEDLL_EXPORTS
#define GPTOOLASSIMPLEDLL_API extern "C"__declspec(dllexport)
#else
#define GPTOOLASSIMPLEDLL_API extern "C"__declspec(dllimport)
#endif
GPTOOLASSIMPLEDLL_API int GPexecutetool(char*, char*);

GPToolAsSimpleDLL ソース ファイルは、指定されたポリゴン フィーチャクラスを開始し、指定のフィールドを各ポリゴン フィーチャのエリアに設定します。記述したすべてのジオプロセシング関数は、すべてが同じ DLL 内にある単純な C 関数エントリ ポイントと、各関数を ArcToolbox に提供するためのスクリプト ツールの付属情報とともに実装できます。

GPTOOLASSIMPLEDLL_API int GPexecutetool(char* featureclassPath, char* fieldname)
{
    // Convert char*s to bstring
    _bstr_t catalogPath;
    catalogPath = featureclasspath;
    _bstr_t newfieldname;
    newfieldname = fieldname;
    // Coinitialize GP utilities class
    IGPUtilitiesPtr ipUtil(CLSID_GPUtilities);
    // Feature class holder
    IFeatureClassPtr ipFeatureclass(0);
    HRESULT hr;
    // Try to fetch feature class from catalog path
    if (FAILED(hr = ipUtil->OpenFeatureClassFromString(catalogPath, &ipFeatureclass)))
    {
        return -1;
    }
    // Index position of the specified field
   	long fieldIndex;
   	ipFeatureclass->FindField(newfieldname, &fieldIndex);
    // Set up query filter and feature cursor
   	IQueryFilterPtr ipFilter(CLSID_QueryFilter);
   	IFeatureCursorPtr ipCursor;
   	IFeaturePtr ipRow;
   	IGeometryPtr ipShape;
    // Open search cursor on feature class
   	ipFeatureclass->Search(ipFilter, VARIANT_FALSE, &ipCursor);
    // Iterate
    esriGeometryType gt;
    for (ipCursor->NextFeature(&ipRow);
       		ipRow != NULL;
         ipCursor->NextFeature(&ipRow))
    {
         // Get row's associated geometry
		       ipRow->get_Shape(&ipShape);
		       // Ensure we've got a polygon
		       ipShape->get_GeometryType(&gt);
		       if (gt != esriGeometryPolygon)
			          return -2;
		       // Get area
		       IAreaPtr ipArea(ipShape);
         double area;
		       ipArea->get_Area(&area);
		       // Pop double into a variant
         VARIANT value;
		       value.vt = VT_R8;
		       value.dblVal = area;
		       // Set double variant onto target field
		       ipRow->put_Value(fieldIndex, value);
	       	// Save
	       	ipRow->Store();
    }
    return S_OK;
}

Python スクリプトはブローカーの役割を果たし、スクリプト ツールから 2 つのパラメーターをテキストとして受け取り、これらのパラメーターをゼロ終端 char* 文字列として DLL 関数に送出します。また、このスクリプトは、DLL 内の関数の呼び出しの前に [フィールドの追加 (Add Field)] ジオプロセシング ツールを使用します。これによって、C++ に独自の機能が実装され、Python に共通のタスクが実装されるので、より堅牢なワークフローにすることができます。

import arcpy
import ctypes
# Get the parameters from the script tool dialog
#
shp = arcpy.GetParameterAsText(0)
fieldName = arcpy.GetParameterAsText(1)
# See if the field already exists in the feature class.
#   If not, add it.
if len(arcpy.ListFields(shp, fieldName)) == 0:
    arcpy.AddField_management(shp, fieldName, "DOUBLE")
# Import DLL into memory and get a pointer to the function
#   Note: be sure the DLL is in your Python search path 
#
dll = ctypes.cdll.GPToolAsSimpleDLL
perform_function = dll.GPExecutetool
# Tell ctypes the function accepts two char* arguments
#
perform_function.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
# Tell ctypes the function return type
#
perform_function.restype = ctypes.c_int
# Call the function in the DLL
#
retval = perform_function(shp, fieldName)
# Check the return value.  If a 0 returned, success!
#
if retval == 0:
    arcpy.AddMessage("Success")
elif retval == 1:
    arcpy.AddError("Unable to open " + shp)
elif retval == 2:
    arcpy.AddError("Not a polygon feature class")

ArcGIS Desktop

  • ホーム
  • ドキュメント
  • サポート

ArcGIS

  • ArcGIS Online
  • ArcGIS Desktop
  • ArcGIS Enterprise
  • ArcGIS
  • ArcGIS Developer
  • ArcGIS Solutions
  • ArcGIS Marketplace

Esri について

  • 会社概要
  • 採用情報
  • Esri ブログ
  • ユーザ カンファレンス
  • デベロッパ サミット
Esri
ご意見・ご感想をお寄せください。
Copyright © 2021 Esri. | プライバシー | リーガル